Spaces:
Runtime error
Runtime error
Shunfeng Zheng
commited on
Upload 89 files
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +2 -0
- 1_SpatialParse.py +404 -0
- GeoLLM/.DS_Store +0 -0
- GeoLLM/__pycache__/llm_ent_extract.cpython-310.pyc +0 -0
- GeoLLM/evaluate.py +161 -0
- GeoLLM/evaluate_GPE.py +159 -0
- GeoLLM/evaluate_RSE.py +183 -0
- GeoLLM/llm_ent_extract.py +114 -0
- GeoLLM/main.py +112 -0
- GeoLLM/test.py +31 -0
- LICENSE +674 -0
- README.md +67 -11
- __pycache__/geospacy.cpython-310.pyc +0 -0
- __pycache__/geospacy.cpython-39.pyc +0 -0
- __pycache__/llm_coding.cpython-310.pyc +0 -0
- __pycache__/llm_ent_extract.cpython-310.pyc +0 -0
- __pycache__/regex_spatial.cpython-310.pyc +0 -0
- __pycache__/regex_spatial.cpython-311.pyc +0 -0
- __pycache__/regex_spatial.cpython-38.pyc +0 -0
- __pycache__/regex_spatial.cpython-39.pyc +0 -0
- answer/.DS_Store +0 -0
- answer/GPT4o.json +171 -0
- call_llm.py +80 -0
- dataset/.DS_Store +0 -0
- dataset/dataset_10.json +166 -0
- dataset/dataset_100.json +1005 -0
- dataset/dataset_10_2.json +171 -0
- dataset/dataset_20.json +174 -0
- dataset/dataset_initial.json +186 -0
- dataset/test.json +18 -0
- db/__pycache__/poly_db_util.cpython-310.pyc +0 -0
- db/__pycache__/poly_db_util.cpython-39.pyc +0 -0
- db/poly_db_util.py +134 -0
- dependencies.txt +102 -0
- disambiguation/__pycache__/disambiguate.cpython-310.pyc +0 -0
- disambiguation/__pycache__/disambiguate.cpython-39.pyc +0 -0
- disambiguation/disambiguate.py +155 -0
- docs/Notes.docx +0 -0
- docs/~$Notes.docx +0 -0
- geocoder/.DS_Store +0 -0
- geocoder/__pycache__/geo_level1.cpython-310.pyc +0 -0
- geocoder/__pycache__/geo_level1.cpython-39.pyc +0 -0
- geocoder/__pycache__/geo_level11.cpython-310.pyc +0 -0
- geocoder/__pycache__/geo_level2.cpython-310.pyc +0 -0
- geocoder/__pycache__/geo_level2.cpython-39.pyc +0 -0
- geocoder/__pycache__/geo_level3.cpython-310.pyc +0 -0
- geocoder/__pycache__/geo_level3.cpython-39.pyc +0 -0
- geocoder/geo_level1.py +185 -0
- geocoder/geo_level11.py +130 -0
- geocoder/geo_level2.py +117 -0
.gitattributes
CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
screen_shot_new.jpg filter=lfs diff=lfs merge=lfs -text
|
37 |
+
screen_shot.jpg filter=lfs diff=lfs merge=lfs -text
|
1_SpatialParse.py
ADDED
@@ -0,0 +1,404 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from spacy import displacy
|
3 |
+
import spacy
|
4 |
+
import geospacy
|
5 |
+
from PIL import Image
|
6 |
+
import base64
|
7 |
+
import sys
|
8 |
+
import pandas as pd
|
9 |
+
import en_core_web_md
|
10 |
+
from spacy.tokens import Span, Doc, Token
|
11 |
+
from utils import geoutil
|
12 |
+
import llm_coding
|
13 |
+
import urllib.parse
|
14 |
+
|
15 |
+
|
16 |
+
colors = {'GPE': "#43c6fc", "LOC": "#fd9720", "RSE":"#a6e22d"}
|
17 |
+
options = {"ents": ['GPE', 'LOC', "RSE"], "colors": colors}
|
18 |
+
|
19 |
+
HTML_WRAPPER = """<div style="overflow-x: auto; border: none solid #a6e22d; border-radius: 0.25rem; padding: 1rem">{}</div>"""
|
20 |
+
model = ""
|
21 |
+
|
22 |
+
gpe_selected = "GPE"
|
23 |
+
loc_selected = "LOC"
|
24 |
+
rse_selected = "RSE"
|
25 |
+
|
26 |
+
types = ""
|
27 |
+
|
28 |
+
#BASE_URL = "http://localhost:8080/"
|
29 |
+
BASE_URL = ""
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
def set_header():
|
34 |
+
LOGO_IMAGE = "tetis-1.png"
|
35 |
+
|
36 |
+
st.markdown(
|
37 |
+
"""
|
38 |
+
<style>
|
39 |
+
.container {
|
40 |
+
display: flex;
|
41 |
+
}
|
42 |
+
.logo-text {
|
43 |
+
font-weight:700 !important;
|
44 |
+
font-size:50px !important;
|
45 |
+
color: #f9a01b !important;
|
46 |
+
padding-left: 10px !important;
|
47 |
+
}
|
48 |
+
.logo-img {
|
49 |
+
float:right;
|
50 |
+
width: 28%;
|
51 |
+
height: 28%;
|
52 |
+
}
|
53 |
+
</style>
|
54 |
+
""",
|
55 |
+
unsafe_allow_html=True
|
56 |
+
)
|
57 |
+
st.markdown(
|
58 |
+
f"""
|
59 |
+
<div class="container">
|
60 |
+
<img class="logo-img" src="data:image/png;base64,{base64.b64encode(open(LOGO_IMAGE, "rb").read()).decode()}">
|
61 |
+
<p class="logo-text">GeOspaCy</p>
|
62 |
+
</div>
|
63 |
+
""",
|
64 |
+
unsafe_allow_html=True
|
65 |
+
)
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
+
def set_side_menu():
|
70 |
+
|
71 |
+
global gpe_selected, loc_selected, rse_selected, model, types
|
72 |
+
types =""
|
73 |
+
params = st.experimental_get_query_params()
|
74 |
+
# params = st.query_params
|
75 |
+
# print(params, 777)
|
76 |
+
|
77 |
+
st.sidebar.markdown("## Spacy Model")
|
78 |
+
st.sidebar.markdown("You can **select** the values of the *spacy model* from Dropdown.")
|
79 |
+
models = ['en_core_web_sm', 'en_core_web_md', 'en_core_web_lg', 'en_core_web_trf']
|
80 |
+
if "model" in params:
|
81 |
+
default_ix = models.index(params["model"][0])
|
82 |
+
else:
|
83 |
+
default_ix = models.index('en_core_web_sm')
|
84 |
+
model = st.sidebar.selectbox('Spacy Model',models, index=default_ix)
|
85 |
+
|
86 |
+
st.sidebar.markdown("## Spatial Entity Labels")
|
87 |
+
st.sidebar.markdown("**Mark** the Spatial Entities you want to extract?")
|
88 |
+
tpes = ""
|
89 |
+
if "type" in params:
|
90 |
+
tpes = params['type'][0]
|
91 |
+
|
92 |
+
if "g" in tpes:
|
93 |
+
gpe = st.sidebar.checkbox('GPE', value = True)
|
94 |
+
else:
|
95 |
+
gpe = st.sidebar.checkbox('GPE')
|
96 |
+
|
97 |
+
if "l" in tpes:
|
98 |
+
loc = st.sidebar.checkbox('LOC', value = True)
|
99 |
+
else:
|
100 |
+
loc = st.sidebar.checkbox('LOC')
|
101 |
+
if "r" in tpes:
|
102 |
+
rse = st.sidebar.checkbox('RSE', value = True)
|
103 |
+
else:
|
104 |
+
rse = st.sidebar.checkbox('RSE')
|
105 |
+
if(gpe):
|
106 |
+
gpe_selected ="GPE"
|
107 |
+
types+="g"
|
108 |
+
|
109 |
+
if(loc):
|
110 |
+
loc_selected ="LOC"
|
111 |
+
types+="l"
|
112 |
+
|
113 |
+
if(rse):
|
114 |
+
rse_selected ="RSE"
|
115 |
+
types+="r"
|
116 |
+
|
117 |
+
|
118 |
+
|
119 |
+
def set_input():
|
120 |
+
params = st.experimental_get_query_params()
|
121 |
+
# params = st.query_params
|
122 |
+
|
123 |
+
if "text" not in params:
|
124 |
+
text = st.text_area("Input unstructured text:", "")
|
125 |
+
else:
|
126 |
+
text = st.text_area("Enter the text to extract {Spatial Entities}", params["text"][0])
|
127 |
+
if(st.button("Extract")):
|
128 |
+
|
129 |
+
# return 'France has detected a highly pathogenic strain of bird flu in a pet shop near Paris, days after an identical outbreak in one of Corsica’s main cities.'
|
130 |
+
|
131 |
+
|
132 |
+
return 'I would like to know where is the area between Burwood and Glebe. Pyrmont.'
|
133 |
+
return '5 km east of Burwood. 3 km south of Glebe. Between Pyrmont and Glebe.'
|
134 |
+
# return 'Between Burwood and Pyrmont.'
|
135 |
+
# return 'Between Burwood and Glebe.'
|
136 |
+
# return 'Between Burwood and Darling Harbour.'
|
137 |
+
# return 'Between China and USA.'
|
138 |
+
# return 'The Burwood city.'
|
139 |
+
# text = "New York is north of Washington. Between Burwood and Pyrmont city."
|
140 |
+
return text
|
141 |
+
|
142 |
+
def set_selected_entities(doc):
|
143 |
+
global gpe_selected, loc_selected, rse_selected, model
|
144 |
+
ents = [ent for ent in doc.ents if ent.label_ == gpe_selected or ent.label_ == loc_selected or ent.label_ == rse_selected]
|
145 |
+
|
146 |
+
doc.ents = ents
|
147 |
+
return doc
|
148 |
+
|
149 |
+
def extract_spatial_entities(text):
|
150 |
+
# nlp = en_core_web_md.load()
|
151 |
+
|
152 |
+
# nlp = spacy.load("en_core_web_md")
|
153 |
+
# nlp.add_pipe("spatial_pipeline", after="ner")
|
154 |
+
# doc = nlp(text)
|
155 |
+
# doc = set_selected_entities(doc)
|
156 |
+
# html = displacy.render(doc, style="ent", options=options)
|
157 |
+
# html = html.replace("\n", "")
|
158 |
+
# st.write(HTML_WRAPPER.format(html), unsafe_allow_html=True)
|
159 |
+
# show_spatial_ent_table(doc, text)
|
160 |
+
|
161 |
+
nlp = spacy.load("en_core_web_md") #####
|
162 |
+
nlp.add_pipe("spatial_pipeline", after="ner")
|
163 |
+
doc = nlp(text)
|
164 |
+
|
165 |
+
# 分句处理
|
166 |
+
sent_ents = []
|
167 |
+
sent_texts = []
|
168 |
+
sent_rse_id = []
|
169 |
+
offset = 0 # 记录当前 token 偏移量
|
170 |
+
sent_start_positions = [0] # 记录句子信息
|
171 |
+
doc_copy = doc.copy() # 用于展示方程组合
|
172 |
+
for sent in doc.sents:
|
173 |
+
|
174 |
+
sent_doc = nlp(sent.text) # 逐句处理
|
175 |
+
sent_doc = set_selected_entities(sent_doc) # 这里处理实体
|
176 |
+
sent_texts.append(sent_doc.text)
|
177 |
+
|
178 |
+
for ent in sent_doc.ents:
|
179 |
+
sent_rse_id.append(ent._.rse_id)
|
180 |
+
# **调整每个实体的索引,使其匹配完整文本**
|
181 |
+
for ent in sent_doc.ents:
|
182 |
+
new_ent = Span(doc, ent.start + offset, ent.end + offset, label=ent.label_)
|
183 |
+
sent_ents.append(new_ent)
|
184 |
+
|
185 |
+
offset += len(sent) # 更新偏移量
|
186 |
+
sent_start_positions.append(sent_start_positions[-1] + len(sent)) # 记录句子起点
|
187 |
+
# **创建新 Doc**
|
188 |
+
final_doc = Doc(nlp.vocab, words=[token.text for token in doc], spaces=[token.whitespace_ for token in doc])
|
189 |
+
for i in sent_start_positions: # 手动标记句子起始点
|
190 |
+
if i < len(final_doc):
|
191 |
+
final_doc[i].is_sent_start = True
|
192 |
+
# **设置实体**
|
193 |
+
final_doc.set_ents(sent_ents)
|
194 |
+
|
195 |
+
for i in range(len(sent_rse_id)):
|
196 |
+
final_doc.ents[i]._.rse_id = sent_rse_id[i]
|
197 |
+
print(doc.ents[0].sent, '原始')
|
198 |
+
doc = final_doc
|
199 |
+
print(doc.ents[0].sent, '新')
|
200 |
+
# 分句处理完毕
|
201 |
+
|
202 |
+
# doc = set_selected_entities(doc)
|
203 |
+
doc.to_disk("saved_doc.spacy")
|
204 |
+
|
205 |
+
|
206 |
+
|
207 |
+
|
208 |
+
html = displacy.render(doc,style="ent", options = options)
|
209 |
+
html = html.replace("\n","")
|
210 |
+
st.write(HTML_WRAPPER.format(html),unsafe_allow_html=True)
|
211 |
+
show_spatial_ent_table(doc, text)
|
212 |
+
|
213 |
+
st.markdown("123123")
|
214 |
+
|
215 |
+
show_sentence_selector_table(doc_copy)
|
216 |
+
|
217 |
+
def show_sentence_selector_table(doc_copy):
|
218 |
+
st.markdown("**______________________________________________________________________________________**")
|
219 |
+
st.markdown("**Sentence Selector for Geographic Composition**")
|
220 |
+
|
221 |
+
# 提取句子
|
222 |
+
sentences = list(doc_copy.sents)
|
223 |
+
|
224 |
+
# 构建表格数据
|
225 |
+
rows = []
|
226 |
+
for idx, sent in enumerate(sentences):
|
227 |
+
sentence_text = sent.text.strip()
|
228 |
+
# 生成跳转链接(定位到Tagger)
|
229 |
+
url = BASE_URL + "Tagger?mode=geocombo&text=" + urllib.parse.quote(sentence_text)
|
230 |
+
new_row = {
|
231 |
+
'Sr.': idx + 1,
|
232 |
+
'sentence': sentence_text,
|
233 |
+
'Select': f'<a target="_self" href="{url}">Select this sentence</a>'
|
234 |
+
}
|
235 |
+
rows.append(new_row)
|
236 |
+
|
237 |
+
# 转为 DataFrame 并渲染为 HTML
|
238 |
+
df = pd.DataFrame(rows)
|
239 |
+
st.write(df.to_html(escape=False, index=False), unsafe_allow_html=True)
|
240 |
+
|
241 |
+
|
242 |
+
|
243 |
+
def show_spatial_ent_table(doc, text):
|
244 |
+
global types
|
245 |
+
if len(doc.ents) > 0:
|
246 |
+
st.markdown("**______________________________________________________________________________________**")
|
247 |
+
st.markdown("**Spatial Entities List**")
|
248 |
+
|
249 |
+
# 初始化一个空 DataFrame
|
250 |
+
df = pd.DataFrame(columns=['Sr.', 'entity', 'label', 'Map', 'GEOJson'])
|
251 |
+
rows = [] # 用于存储所有行
|
252 |
+
|
253 |
+
for ent in doc.ents:
|
254 |
+
url_map = BASE_URL + "Tagger?map=true&type=" + types + "&model=" + model + "&text=" + text + "&entity=" + ent._.rse_id
|
255 |
+
print(url_map, 'uuurrr')
|
256 |
+
print(ent._.rse_id, 'pppp')
|
257 |
+
url_json = BASE_URL + "Tagger?geojson=true&type=" + types + "&model=" + model + "&text=" + text + "&entity=" + ent._.rse_id
|
258 |
+
|
259 |
+
# 创建新行
|
260 |
+
new_row = {
|
261 |
+
'Sr.': len(rows) + 1,
|
262 |
+
'entity': ent.text,
|
263 |
+
'label': ent.label_,
|
264 |
+
'Map': f'<a target="_self" href="{url_map}">View</a>',
|
265 |
+
'GEOJson': f'<a target="_self" href="{url_json}">View</a>'
|
266 |
+
}
|
267 |
+
|
268 |
+
rows.append(new_row) # 将新行添加到列表中
|
269 |
+
|
270 |
+
# 将所有行转为 DataFrame
|
271 |
+
df = pd.DataFrame(rows)
|
272 |
+
|
273 |
+
# 使用 Streamlit 显示 HTML 表格
|
274 |
+
st.write(df.to_html(escape=False, index=False), unsafe_allow_html=True)
|
275 |
+
|
276 |
+
# params = st.experimental_get_query_params()
|
277 |
+
# params = st.query_params
|
278 |
+
# ase, level_1, level_2, level_3 = geoutil.get_ent(params["entity"][0])
|
279 |
+
# print(geoutil.get_ent(params), 'ppppp')
|
280 |
+
|
281 |
+
def set_header(): # tetis Geospacy LOGO
|
282 |
+
LOGO_IMAGE = "title.jpg"
|
283 |
+
|
284 |
+
st.markdown(
|
285 |
+
"""
|
286 |
+
<style>
|
287 |
+
.container {
|
288 |
+
display: flex;
|
289 |
+
}
|
290 |
+
.logo-text {
|
291 |
+
font-weight:700 !important;
|
292 |
+
font-size:50px !important;
|
293 |
+
color: #52aee3 !important;
|
294 |
+
padding-left: 10px !important;
|
295 |
+
}
|
296 |
+
.logo-img {
|
297 |
+
float:right;
|
298 |
+
width: 10%;
|
299 |
+
height: 10%;
|
300 |
+
}
|
301 |
+
</style>
|
302 |
+
""",
|
303 |
+
unsafe_allow_html=True
|
304 |
+
)
|
305 |
+
st.markdown(
|
306 |
+
f"""
|
307 |
+
<div class="container">
|
308 |
+
<img class="logo-img" src="data:image/png;base64,{base64.b64encode(open(LOGO_IMAGE, "rb").read()).decode()}">
|
309 |
+
<p class="logo-text">SpatialParse</p>
|
310 |
+
</div>
|
311 |
+
""",
|
312 |
+
unsafe_allow_html=True
|
313 |
+
)
|
314 |
+
|
315 |
+
|
316 |
+
def set_side_menu():
|
317 |
+
global gpe_selected, loc_selected, rse_selected, model, types
|
318 |
+
types = ""
|
319 |
+
params = st.experimental_get_query_params()
|
320 |
+
st.sidebar.markdown("## Deployment Method")
|
321 |
+
st.sidebar.markdown("You can select the deployment method for the model.")
|
322 |
+
deployment_options = ["API", "Local deployment"]
|
323 |
+
use_local_model = st.sidebar.radio("Choose deployment method:", deployment_options, index=0) == "Local deployment"
|
324 |
+
|
325 |
+
if use_local_model:
|
326 |
+
local_model_path = st.sidebar.text_input("Enter local model path:", "")
|
327 |
+
|
328 |
+
st.sidebar.markdown("## LLM Model")
|
329 |
+
st.sidebar.markdown("You can **select** different *LLM model* powered by API.")
|
330 |
+
models = ['Llama-3-8B', 'Mistral-7B-0.3', 'Gemma-2-10B', 'GPT-4o', 'Gemini Pro', 'Deepseek-R1', 'en_core_web_sm', 'en_core_web_md', 'en_core_web_lg', 'en_core_web_trf']
|
331 |
+
|
332 |
+
|
333 |
+
|
334 |
+
|
335 |
+
if "model" in params:
|
336 |
+
default_ix = models.index(params["model"][0])
|
337 |
+
else:
|
338 |
+
default_ix = models.index('GPT-4o')
|
339 |
+
|
340 |
+
|
341 |
+
|
342 |
+
|
343 |
+
model = st.sidebar.selectbox('LLM Model', models, index=default_ix)
|
344 |
+
|
345 |
+
st.sidebar.markdown("## Spatial Entity Labels")
|
346 |
+
|
347 |
+
st.sidebar.markdown("Please **Mark** the Spatial Entities you want to extract.")
|
348 |
+
tpes = ""
|
349 |
+
if "type" in params:
|
350 |
+
tpes = params['type'][0]
|
351 |
+
|
352 |
+
st.sidebar.markdown("### Absolute Spatial Entity:")
|
353 |
+
if "g" in tpes:
|
354 |
+
gpe = st.sidebar.checkbox('GPE', value=True)
|
355 |
+
else:
|
356 |
+
gpe = st.sidebar.checkbox('GPE')
|
357 |
+
|
358 |
+
if "l" in tpes:
|
359 |
+
loc = st.sidebar.checkbox('LOC', value=True)
|
360 |
+
else:
|
361 |
+
loc = st.sidebar.checkbox('LOC')
|
362 |
+
|
363 |
+
st.sidebar.markdown("### Relative Spatial Entity:")
|
364 |
+
|
365 |
+
if "r" in tpes:
|
366 |
+
rse = st.sidebar.checkbox('RSE', value=True)
|
367 |
+
else:
|
368 |
+
rse = st.sidebar.checkbox('RSE')
|
369 |
+
if (gpe):
|
370 |
+
gpe_selected = "GPE"
|
371 |
+
types += "g"
|
372 |
+
|
373 |
+
if (loc):
|
374 |
+
loc_selected = "LOC"
|
375 |
+
types += "l"
|
376 |
+
|
377 |
+
if (rse):
|
378 |
+
rse_selected = "RSE"
|
379 |
+
types += "r"
|
380 |
+
|
381 |
+
|
382 |
+
|
383 |
+
|
384 |
+
|
385 |
+
def main():
|
386 |
+
global gpe_selected, loc_selected, rse_selected, model
|
387 |
+
#print(displacy.templates.TPL_ENT)
|
388 |
+
set_header()
|
389 |
+
set_side_menu()
|
390 |
+
|
391 |
+
|
392 |
+
text = set_input()
|
393 |
+
|
394 |
+
if(text is not None):
|
395 |
+
extract_spatial_entities(text)
|
396 |
+
elif "text" in st.session_state:
|
397 |
+
text = st.session_state.text
|
398 |
+
extract_spatial_entities(text)
|
399 |
+
|
400 |
+
|
401 |
+
if __name__ == '__main__':
|
402 |
+
main()
|
403 |
+
|
404 |
+
|
GeoLLM/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
GeoLLM/__pycache__/llm_ent_extract.cpython-310.pyc
ADDED
Binary file (6.22 kB). View file
|
|
GeoLLM/evaluate.py
ADDED
@@ -0,0 +1,161 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import re
|
3 |
+
|
4 |
+
client = OpenAI(
|
5 |
+
api_key='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'
|
6 |
+
)
|
7 |
+
|
8 |
+
model = "gpt-3.5-turbo"
|
9 |
+
model = "gpt-4o"
|
10 |
+
|
11 |
+
def extract_GPE(text):
|
12 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all geopolitical entities from a given text. Geopolitical entities can include countries, regions, cities, autonomous regions, or other administrative divisions. For each geopolitical entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
13 |
+
sent = 'Where is France?'
|
14 |
+
|
15 |
+
math_bot_messages = [
|
16 |
+
{"role": "system",
|
17 |
+
"content": system_prompt},
|
18 |
+
{"role": "user", "content": text},
|
19 |
+
]
|
20 |
+
|
21 |
+
chat_completion = client.chat.completions.create(
|
22 |
+
messages=math_bot_messages,
|
23 |
+
model=model,
|
24 |
+
)
|
25 |
+
|
26 |
+
result = chat_completion.choices[0].message.content
|
27 |
+
return extract_to_dict(result, 'GPE')
|
28 |
+
|
29 |
+
|
30 |
+
def extract_LOC(text):
|
31 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all location entities (LOC) from a given text. Location entities can include physical locations such as landmarks, geographical features, mountains, rivers, oceans, and places, but do not include political or administrative divisions such as countries or cities (these are considered geopolitical entities). For each location entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
32 |
+
sent = 'The Grand Canyon is one of the most spectacular natural wonders in the world, located in the state of Arizona. Nearby, the Colorado River flows through the canyon, carving its way through the rugged terrain. In the north, the Rocky Mountains stretch across several states, including Colorado and Wyoming.'
|
33 |
+
|
34 |
+
math_bot_messages = [
|
35 |
+
{"role": "system",
|
36 |
+
"content": system_prompt},
|
37 |
+
{"role": "user", "content": text},
|
38 |
+
]
|
39 |
+
|
40 |
+
chat_completion = client.chat.completions.create(
|
41 |
+
messages=math_bot_messages,
|
42 |
+
model=model,
|
43 |
+
)
|
44 |
+
|
45 |
+
result = chat_completion.choices[0].message.content
|
46 |
+
return extract_to_dict(result, 'LOC')
|
47 |
+
|
48 |
+
|
49 |
+
def extract_RSE_1(text):
|
50 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all spatial entities (directional keywords) from a given text. Spatial entities can include directional keywords such as north, south, east, west, and more specific terms like northeast, northwest, southeast, southwest, as well as terms indicating locations like center, central, downtown, and midtown. For each spatial entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The hotel is located in the downtown area of New York, just south of Central Park, with a beautiful view of the southeast corner."\n\nExpected Output:\n[###downtown###, ###south###, ###southeast###]'''
|
51 |
+
sent = 'The train station is situated in the central part of the city, just north of the river and east of the main square.'
|
52 |
+
|
53 |
+
math_bot_messages = [
|
54 |
+
{"role": "system",
|
55 |
+
"content": system_prompt},
|
56 |
+
{"role": "user", "content": text},
|
57 |
+
]
|
58 |
+
|
59 |
+
chat_completion = client.chat.completions.create(
|
60 |
+
messages=math_bot_messages,
|
61 |
+
model=model,
|
62 |
+
)
|
63 |
+
|
64 |
+
result = chat_completion.choices[0].message.content
|
65 |
+
return extract_to_dict(result, 'RES_1')
|
66 |
+
|
67 |
+
|
68 |
+
def extract_RSE_2(text):
|
69 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy spatial entities (keywords) from a given text. Fuzzy spatial keywords can include terms like nearby, near, vicinity, close, beside, next, adjacent, immediate, border, surrounding, neighbourhood, proximity, territory, locality, and similar terms. For each fuzzy spatial keyword, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located nearby the lake, with several cafes close to the walking paths, and a small garden adjacent to the main entrance."\n\nExpected Output:\n[###nearby###, ###close###, ###adjacent###]'''
|
70 |
+
sent = 'The village is situated in the vicinity of the mountain range, with a small river flowing beside the houses and several farms next to the road.'
|
71 |
+
|
72 |
+
math_bot_messages = [
|
73 |
+
{"role": "system",
|
74 |
+
"content": system_prompt},
|
75 |
+
{"role": "user", "content": text},
|
76 |
+
]
|
77 |
+
|
78 |
+
chat_completion = client.chat.completions.create(
|
79 |
+
messages=math_bot_messages,
|
80 |
+
model=model,
|
81 |
+
)
|
82 |
+
|
83 |
+
result = chat_completion.choices[0].message.content
|
84 |
+
return extract_to_dict(result, 'RES_2')
|
85 |
+
|
86 |
+
|
87 |
+
def extract_RSE_3(text):
|
88 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy distance keywords from a given text. Fuzzy distance keywords include numeric values followed by distance units such as kilometer, mile, meter, foot, inch, centimeter, and other related units. The distance units can be in different formats, such as km, m, mi, ft, yd, cm, mm, or even in full words like kilometer, mile, or inch. For each fuzzy distance keyword, wrap the entire expression (number and unit) in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located 3 km away from the city center, while the nearest supermarket is only 500 meters from here, and the lake is about 1 mile further down the road."\n\nExpected Output:\n[###3 km###, ###500 meters###, ###1 mile###]'''
|
89 |
+
sent = 'The school is located approximately 2 miles from the station, while the nearest bus stop is 200 meters away. The hiking trail is about 5 kilometers east of the town center.'
|
90 |
+
|
91 |
+
math_bot_messages = [
|
92 |
+
{"role": "system",
|
93 |
+
"content": system_prompt},
|
94 |
+
{"role": "user", "content": text},
|
95 |
+
]
|
96 |
+
|
97 |
+
chat_completion = client.chat.completions.create(
|
98 |
+
messages=math_bot_messages,
|
99 |
+
model=model,
|
100 |
+
)
|
101 |
+
|
102 |
+
result = chat_completion.choices[0].message.content
|
103 |
+
return extract_to_dict(result, 'RES_3')
|
104 |
+
|
105 |
+
|
106 |
+
def extract_to_dict(respond, label):
|
107 |
+
# Extract entities from the response
|
108 |
+
entities = re.findall(r'###(.*?)###', respond)
|
109 |
+
|
110 |
+
# Create dictionary with entity names as keys and 'GPE' as values
|
111 |
+
entity_dict = {entity: label for entity in entities}
|
112 |
+
|
113 |
+
return entity_dict
|
114 |
+
|
115 |
+
|
116 |
+
# dataset = []
|
117 |
+
#
|
118 |
+
# # for i in dataset:
|
119 |
+
#
|
120 |
+
# with open('tweets.dev.bio', 'r') as file:
|
121 |
+
# for line in file:
|
122 |
+
# print(line.strip())
|
123 |
+
|
124 |
+
|
125 |
+
# test GPT GPE LOC
|
126 |
+
from datasets import load_dataset
|
127 |
+
dataset = load_dataset("eriktks/conll2003")
|
128 |
+
test_data = dataset["test"]
|
129 |
+
filtered_data = test_data.filter(lambda example: 4 in example['ner_tags'])
|
130 |
+
random_sample = filtered_data.shuffle(seed=42).select([i for i in range(10)])
|
131 |
+
for i, example in enumerate(random_sample):
|
132 |
+
non_zero_tokens = [(example['tokens'][j], example['ner_tags'][j]) for j in range(len(example['ner_tags'])) if
|
133 |
+
example['ner_tags'][j] != 0]
|
134 |
+
tokens_string = ' '.join(example['tokens'])
|
135 |
+
print(f"Sample {i + 1}:")
|
136 |
+
print(f"Tokens: {tokens_string}")
|
137 |
+
print(f"Non-zero ner_tags and corresponding tokens: {non_zero_tokens}")
|
138 |
+
print(extract_GPE(tokens_string))
|
139 |
+
print("-" * 50)
|
140 |
+
|
141 |
+
# test GPT RSE
|
142 |
+
# sentences = [
|
143 |
+
# "The parade took place about 10 kilometers east of downtown Sydney.",
|
144 |
+
# "The origin of the virus is believed to be near Houston, Texas.",
|
145 |
+
# "The company’s new headquarters is located roughly 5 miles south of the city center.",
|
146 |
+
# "The discovery was made just north of the Arctic Circle, in the remote tundra.",
|
147 |
+
# "The train station lies approximately 15 kilometers west of the airport.",
|
148 |
+
# "The ancient ruins are located on the hilltop, overlooking the valley to the south.",
|
149 |
+
# "The earthquake's epicenter was found around 50 kilometers southwest of Tokyo.",
|
150 |
+
# "The forest stretches for several kilometers to the east, beyond the small village.",
|
151 |
+
# "The research facility is positioned at the foot of the mountains, 30 kilometers southeast of the capital.",
|
152 |
+
# "The new shopping mall is situated directly across from the park, just a few blocks north of the river."
|
153 |
+
# ]
|
154 |
+
# for i in sentences:
|
155 |
+
# print(i)
|
156 |
+
# print(extract_RSE_1(i))
|
157 |
+
# print(extract_RSE_2(i))
|
158 |
+
# print(extract_RSE_3(i))
|
159 |
+
# print("-" * 50)
|
160 |
+
|
161 |
+
|
GeoLLM/evaluate_GPE.py
ADDED
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import re
|
3 |
+
|
4 |
+
client = OpenAI(
|
5 |
+
api_key='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'
|
6 |
+
)
|
7 |
+
|
8 |
+
model = "gpt-3.5-turbo"
|
9 |
+
model = "gpt-4o"
|
10 |
+
|
11 |
+
def extract_GPE(text):
|
12 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all geopolitical entities from a given text. Geopolitical entities can include countries, regions, cities, autonomous regions, or other administrative divisions. For each geopolitical entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
13 |
+
sent = 'Where is France?'
|
14 |
+
|
15 |
+
math_bot_messages = [
|
16 |
+
{"role": "system",
|
17 |
+
"content": system_prompt},
|
18 |
+
{"role": "user", "content": text},
|
19 |
+
]
|
20 |
+
|
21 |
+
chat_completion = client.chat.completions.create(
|
22 |
+
messages=math_bot_messages,
|
23 |
+
model=model,
|
24 |
+
)
|
25 |
+
|
26 |
+
result = chat_completion.choices[0].message.content
|
27 |
+
return extract_to_dict(result, 'GPE')
|
28 |
+
|
29 |
+
|
30 |
+
def extract_LOC(text):
|
31 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all location entities (LOC) from a given text. Location entities can include physical locations such as landmarks, geographical features, mountains, rivers, oceans, and places, but do not include political or administrative divisions such as countries or cities (these are considered geopolitical entities). For each location entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
32 |
+
sent = 'The Grand Canyon is one of the most spectacular natural wonders in the world, located in the state of Arizona. Nearby, the Colorado River flows through the canyon, carving its way through the rugged terrain. In the north, the Rocky Mountains stretch across several states, including Colorado and Wyoming.'
|
33 |
+
|
34 |
+
math_bot_messages = [
|
35 |
+
{"role": "system",
|
36 |
+
"content": system_prompt},
|
37 |
+
{"role": "user", "content": text},
|
38 |
+
]
|
39 |
+
|
40 |
+
chat_completion = client.chat.completions.create(
|
41 |
+
messages=math_bot_messages,
|
42 |
+
model=model,
|
43 |
+
)
|
44 |
+
|
45 |
+
result = chat_completion.choices[0].message.content
|
46 |
+
return extract_to_dict(result, 'LOC')
|
47 |
+
|
48 |
+
|
49 |
+
def extract_RSE_1(text):
|
50 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all spatial entities (directional keywords) from a given text. Spatial entities can include directional keywords such as north, south, east, west, and more specific terms like northeast, northwest, southeast, southwest, as well as terms indicating locations like center, central, downtown, and midtown. For each spatial entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The hotel is located in the downtown area of New York, just south of Central Park, with a beautiful view of the southeast corner."\n\nExpected Output:\n[###downtown###, ###south###, ###southeast###]'''
|
51 |
+
sent = 'The train station is situated in the central part of the city, just north of the river and east of the main square.'
|
52 |
+
|
53 |
+
math_bot_messages = [
|
54 |
+
{"role": "system",
|
55 |
+
"content": system_prompt},
|
56 |
+
{"role": "user", "content": text},
|
57 |
+
]
|
58 |
+
|
59 |
+
chat_completion = client.chat.completions.create(
|
60 |
+
messages=math_bot_messages,
|
61 |
+
model=model,
|
62 |
+
)
|
63 |
+
|
64 |
+
result = chat_completion.choices[0].message.content
|
65 |
+
return extract_to_dict(result, 'RES_1')
|
66 |
+
|
67 |
+
|
68 |
+
def extract_RSE_2(text):
|
69 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy spatial entities (keywords) from a given text. Fuzzy spatial keywords can include terms like nearby, near, vicinity, close, beside, next, adjacent, immediate, border, surrounding, neighbourhood, proximity, territory, locality, and similar terms. For each fuzzy spatial keyword, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located nearby the lake, with several cafes close to the walking paths, and a small garden adjacent to the main entrance."\n\nExpected Output:\n[###nearby###, ###close###, ###adjacent###]'''
|
70 |
+
sent = 'The village is situated in the vicinity of the mountain range, with a small river flowing beside the houses and several farms next to the road.'
|
71 |
+
|
72 |
+
math_bot_messages = [
|
73 |
+
{"role": "system",
|
74 |
+
"content": system_prompt},
|
75 |
+
{"role": "user", "content": text},
|
76 |
+
]
|
77 |
+
|
78 |
+
chat_completion = client.chat.completions.create(
|
79 |
+
messages=math_bot_messages,
|
80 |
+
model=model,
|
81 |
+
)
|
82 |
+
|
83 |
+
result = chat_completion.choices[0].message.content
|
84 |
+
return extract_to_dict(result, 'RES_2')
|
85 |
+
|
86 |
+
|
87 |
+
def extract_RSE_3(text):
|
88 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy distance keywords from a given text. Fuzzy distance keywords include numeric values followed by distance units such as kilometer, mile, meter, foot, inch, centimeter, and other related units. The distance units can be in different formats, such as km, m, mi, ft, yd, cm, mm, or even in full words like kilometer, mile, or inch. For each fuzzy distance keyword, wrap the entire expression (number and unit) in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located 3 km away from the city center, while the nearest supermarket is only 500 meters from here, and the lake is about 1 mile further down the road."\n\nExpected Output:\n[###3 km###, ###500 meters###, ###1 mile###]'''
|
89 |
+
sent = 'The school is located approximately 2 miles from the station, while the nearest bus stop is 200 meters away. The hiking trail is about 5 kilometers east of the town center.'
|
90 |
+
|
91 |
+
math_bot_messages = [
|
92 |
+
{"role": "system",
|
93 |
+
"content": system_prompt},
|
94 |
+
{"role": "user", "content": text},
|
95 |
+
]
|
96 |
+
|
97 |
+
chat_completion = client.chat.completions.create(
|
98 |
+
messages=math_bot_messages,
|
99 |
+
model=model,
|
100 |
+
)
|
101 |
+
|
102 |
+
result = chat_completion.choices[0].message.content
|
103 |
+
return extract_to_dict(result, 'RES_3')
|
104 |
+
|
105 |
+
|
106 |
+
def extract_to_dict(respond, label):
|
107 |
+
# Extract entities from the response
|
108 |
+
entities = re.findall(r'###(.*?)###', respond)
|
109 |
+
|
110 |
+
# Create dictionary with entity names as keys and 'GPE' as values
|
111 |
+
entity_dict = {entity: label for entity in entities}
|
112 |
+
|
113 |
+
return entity_dict
|
114 |
+
|
115 |
+
|
116 |
+
|
117 |
+
|
118 |
+
# test GPT GPE LOC
|
119 |
+
from datasets import load_dataset
|
120 |
+
|
121 |
+
# 加载数据集
|
122 |
+
dataset = load_dataset("eriktks/conll2003")
|
123 |
+
# dataset = load_dataset("tner/ontonotes5")
|
124 |
+
test_data = dataset["test"]
|
125 |
+
|
126 |
+
# 过滤出包含 ner_tag 为 4 的数据
|
127 |
+
filtered_data = test_data.filter(lambda example: 4 in example['ner_tags'])
|
128 |
+
|
129 |
+
# 随机抽取 350 个样本
|
130 |
+
random_sample = filtered_data.shuffle(seed=42).select([i for i in range(350)])
|
131 |
+
|
132 |
+
# 计算正确数
|
133 |
+
correct_count = 0
|
134 |
+
|
135 |
+
for i, example in enumerate(random_sample):
|
136 |
+
# 取出非零的 ner_tags 和对应的 tokens
|
137 |
+
non_zero_tokens = {example['tokens'][j]: example['ner_tags'][j] for j in range(len(example['ner_tags'])) if example['ner_tags'][j] != 0}
|
138 |
+
|
139 |
+
# 生成 tokens 的字符串
|
140 |
+
tokens_string = ' '.join(example['tokens'])
|
141 |
+
|
142 |
+
# 调用 extract_GPE 函数获取提取的 GPE 结果(一个字典)
|
143 |
+
extracted_gpe = extract_GPE(tokens_string) # 确保 extract_GPE 返回的是字典
|
144 |
+
|
145 |
+
# 计算正确的匹配数
|
146 |
+
for token in non_zero_tokens.keys():
|
147 |
+
if token in extracted_gpe:
|
148 |
+
correct_count += 1
|
149 |
+
break
|
150 |
+
|
151 |
+
# 计算准确率
|
152 |
+
accuracy = correct_count / len(random_sample)
|
153 |
+
|
154 |
+
print(f"Total samples: {len(random_sample)}")
|
155 |
+
print(f"Correctly identified samples: {correct_count}")
|
156 |
+
print(f"Accuracy: {accuracy:.2%}")
|
157 |
+
|
158 |
+
|
159 |
+
|
GeoLLM/evaluate_RSE.py
ADDED
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import re
|
3 |
+
|
4 |
+
client = OpenAI(
|
5 |
+
api_key='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'
|
6 |
+
)
|
7 |
+
|
8 |
+
model = "gpt-3.5-turbo"
|
9 |
+
model = "gpt-4o"
|
10 |
+
|
11 |
+
def extract_GPE(text):
|
12 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all geopolitical entities from a given text. Geopolitical entities can include countries, regions, cities, autonomous regions, or other administrative divisions. For each geopolitical entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
13 |
+
sent = 'Where is France?'
|
14 |
+
|
15 |
+
math_bot_messages = [
|
16 |
+
{"role": "system",
|
17 |
+
"content": system_prompt},
|
18 |
+
{"role": "user", "content": text},
|
19 |
+
]
|
20 |
+
|
21 |
+
chat_completion = client.chat.completions.create(
|
22 |
+
messages=math_bot_messages,
|
23 |
+
model=model,
|
24 |
+
)
|
25 |
+
|
26 |
+
result = chat_completion.choices[0].message.content
|
27 |
+
return extract_to_dict(result, 'GPE')
|
28 |
+
|
29 |
+
|
30 |
+
def extract_LOC(text):
|
31 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all location entities (LOC) from a given text. Location entities can include physical locations such as landmarks, geographical features, mountains, rivers, oceans, and places, but do not include political or administrative divisions such as countries or cities (these are considered geopolitical entities). For each location entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
32 |
+
sent = 'The Grand Canyon is one of the most spectacular natural wonders in the world, located in the state of Arizona. Nearby, the Colorado River flows through the canyon, carving its way through the rugged terrain. In the north, the Rocky Mountains stretch across several states, including Colorado and Wyoming.'
|
33 |
+
|
34 |
+
math_bot_messages = [
|
35 |
+
{"role": "system",
|
36 |
+
"content": system_prompt},
|
37 |
+
{"role": "user", "content": text},
|
38 |
+
]
|
39 |
+
|
40 |
+
chat_completion = client.chat.completions.create(
|
41 |
+
messages=math_bot_messages,
|
42 |
+
model=model,
|
43 |
+
)
|
44 |
+
|
45 |
+
result = chat_completion.choices[0].message.content
|
46 |
+
return extract_to_dict(result, 'LOC')
|
47 |
+
|
48 |
+
|
49 |
+
def extract_RSE_1(text):
|
50 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all spatial entities (directional keywords) from a given text. Spatial entities can include directional keywords such as north, south, east, west, and more specific terms like northeast, northwest, southeast, southwest, as well as terms indicating locations like center, central, downtown, and midtown. For each spatial entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The hotel is located in the downtown area of New York, just south of Central Park, with a beautiful view of the southeast corner."\n\nExpected Output:\n[###downtown###, ###south###, ###southeast###]'''
|
51 |
+
sent = 'The train station is situated in the central part of the city, just north of the river and east of the main square.'
|
52 |
+
|
53 |
+
math_bot_messages = [
|
54 |
+
{"role": "system",
|
55 |
+
"content": system_prompt},
|
56 |
+
{"role": "user", "content": text},
|
57 |
+
]
|
58 |
+
|
59 |
+
chat_completion = client.chat.completions.create(
|
60 |
+
messages=math_bot_messages,
|
61 |
+
model=model,
|
62 |
+
)
|
63 |
+
|
64 |
+
result = chat_completion.choices[0].message.content
|
65 |
+
return extract_to_dict(result, 'RES_1')
|
66 |
+
|
67 |
+
|
68 |
+
def extract_RSE_2(text):
|
69 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy spatial entities (keywords) from a given text. Fuzzy spatial keywords can include terms like nearby, near, vicinity, close, beside, next, adjacent, immediate, border, surrounding, neighbourhood, proximity, territory, locality, and similar terms. For each fuzzy spatial keyword, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located nearby the lake, with several cafes close to the walking paths, and a small garden adjacent to the main entrance."\n\nExpected Output:\n[###nearby###, ###close###, ###adjacent###]'''
|
70 |
+
sent = 'The village is situated in the vicinity of the mountain range, with a small river flowing beside the houses and several farms next to the road.'
|
71 |
+
|
72 |
+
math_bot_messages = [
|
73 |
+
{"role": "system",
|
74 |
+
"content": system_prompt},
|
75 |
+
{"role": "user", "content": text},
|
76 |
+
]
|
77 |
+
|
78 |
+
chat_completion = client.chat.completions.create(
|
79 |
+
messages=math_bot_messages,
|
80 |
+
model=model,
|
81 |
+
)
|
82 |
+
|
83 |
+
result = chat_completion.choices[0].message.content
|
84 |
+
return extract_to_dict(result, 'RES_2')
|
85 |
+
|
86 |
+
|
87 |
+
def extract_RSE_3(text):
|
88 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy distance keywords from a given text. Fuzzy distance keywords include numeric values followed by distance units such as kilometer, mile, meter, foot, inch, centimeter, and other related units. The distance units can be in different formats, such as km, m, mi, ft, yd, cm, mm, or even in full words like kilometer, mile, or inch. For each fuzzy distance keyword, wrap the entire expression (number and unit) in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located 3 km away from the city center, while the nearest supermarket is only 500 meters from here, and the lake is about 1 mile further down the road."\n\nExpected Output:\n[###3 km###, ###500 meters###, ###1 mile###]'''
|
89 |
+
sent = 'The school is located approximately 2 miles from the station, while the nearest bus stop is 200 meters away. The hiking trail is about 5 kilometers east of the town center.'
|
90 |
+
|
91 |
+
math_bot_messages = [
|
92 |
+
{"role": "system",
|
93 |
+
"content": system_prompt},
|
94 |
+
{"role": "user", "content": text},
|
95 |
+
]
|
96 |
+
|
97 |
+
chat_completion = client.chat.completions.create(
|
98 |
+
messages=math_bot_messages,
|
99 |
+
model=model,
|
100 |
+
)
|
101 |
+
|
102 |
+
result = chat_completion.choices[0].message.content
|
103 |
+
return extract_to_dict(result, 'RES_3')
|
104 |
+
|
105 |
+
|
106 |
+
def extract_to_dict(respond, label):
|
107 |
+
# Extract entities from the response
|
108 |
+
entities = re.findall(r'###(.*?)###', respond)
|
109 |
+
|
110 |
+
# Create dictionary with entity names as keys and 'GPE' as values
|
111 |
+
entity_dict = {entity: label for entity in entities}
|
112 |
+
|
113 |
+
return entity_dict
|
114 |
+
|
115 |
+
|
116 |
+
def read_bio_file(file_path):
|
117 |
+
"""
|
118 |
+
读取 .bio 文件,并将每个文档的数据拆分成独立的列表
|
119 |
+
:param file_path: BIO 文件路径 (xxx.bio)
|
120 |
+
:return: 一个包含多个文档的列表,每个文档是 (tokens, labels) 的元组
|
121 |
+
"""
|
122 |
+
documents = []
|
123 |
+
tokens, labels = [], []
|
124 |
+
|
125 |
+
with open(file_path, 'r', encoding='utf-8') as file:
|
126 |
+
for line in file:
|
127 |
+
line = line.strip()
|
128 |
+
if not line:
|
129 |
+
continue # 跳过空行
|
130 |
+
|
131 |
+
parts = line.split()
|
132 |
+
if len(parts) == 2:
|
133 |
+
token, label = parts
|
134 |
+
|
135 |
+
# 遇到 -DOCSTART- 说明是新文档的开始
|
136 |
+
if token == "-DOCSTART-":
|
137 |
+
if tokens and labels:
|
138 |
+
# 之前的文档存入 documents
|
139 |
+
documents.append((tokens, labels))
|
140 |
+
# 开始新的文档
|
141 |
+
tokens, labels = [], []
|
142 |
+
|
143 |
+
tokens.append(token)
|
144 |
+
labels.append(label)
|
145 |
+
|
146 |
+
# 处理最后一个文档
|
147 |
+
if tokens and labels:
|
148 |
+
documents.append((tokens, labels))
|
149 |
+
|
150 |
+
return documents
|
151 |
+
|
152 |
+
# test GPT GPE LOC
|
153 |
+
from datasets import load_dataset
|
154 |
+
|
155 |
+
# 加载数据集
|
156 |
+
dataset = read_bio_file(bio_filename)
|
157 |
+
|
158 |
+
|
159 |
+
|
160 |
+
filtered_data = dataset.filter(lambda example: 4 in example['ner_tags'])
|
161 |
+
|
162 |
+
# 随机抽取 350 个样本
|
163 |
+
random_sample = filtered_data.shuffle(seed=42).select([i for i in range(350)])
|
164 |
+
|
165 |
+
# 计算正确数
|
166 |
+
correct_count = 0
|
167 |
+
|
168 |
+
for i, example in enumerate(random_sample):
|
169 |
+
# 取出非零的 ner_tags 和对应的 tokens
|
170 |
+
non_zero_tokens = {example['tokens'][j]: example['ner_tags'][j] for j in range(len(example['ner_tags'])) if example['ner_tags'][j] != 0}
|
171 |
+
|
172 |
+
# 生成 tokens 的字符串
|
173 |
+
tokens_string = ' '.join(example['tokens'])
|
174 |
+
|
175 |
+
|
176 |
+
extracted_1 = extract_RSE_1(tokens_string)
|
177 |
+
extracted_2 = extract_RSE_2(tokens_string)
|
178 |
+
extracted_3 = extract_RSE_3(tokens_string)
|
179 |
+
print(extracted_1, '//',extracted_2, '//', extracted_3)
|
180 |
+
|
181 |
+
|
182 |
+
|
183 |
+
|
GeoLLM/llm_ent_extract.py
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import re
|
3 |
+
|
4 |
+
client = OpenAI(
|
5 |
+
api_key='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'
|
6 |
+
)
|
7 |
+
|
8 |
+
model = "gpt-3.5-turbo"
|
9 |
+
|
10 |
+
def extract_GPE(text):
|
11 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all geopolitical entities from a given text. Geopolitical entities can include countries, regions, cities, autonomous regions, or other administrative divisions. For each geopolitical entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
12 |
+
sent = 'Where is France?'
|
13 |
+
|
14 |
+
math_bot_messages = [
|
15 |
+
{"role": "system",
|
16 |
+
"content": system_prompt},
|
17 |
+
{"role": "user", "content": text},
|
18 |
+
]
|
19 |
+
|
20 |
+
chat_completion = client.chat.completions.create(
|
21 |
+
messages=math_bot_messages,
|
22 |
+
model=model,
|
23 |
+
)
|
24 |
+
|
25 |
+
result = chat_completion.choices[0].message.content
|
26 |
+
return result
|
27 |
+
|
28 |
+
|
29 |
+
def extract_LOC(text):
|
30 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all location entities (LOC) from a given text. Location entities can include physical locations such as landmarks, geographical features, mountains, rivers, oceans, and places, but do not include political or administrative divisions such as countries or cities (these are considered geopolitical entities). For each location entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
31 |
+
sent = 'The Grand Canyon is one of the most spectacular natural wonders in the world, located in the state of Arizona. Nearby, the Colorado River flows through the canyon, carving its way through the rugged terrain. In the north, the Rocky Mountains stretch across several states, including Colorado and Wyoming.'
|
32 |
+
|
33 |
+
math_bot_messages = [
|
34 |
+
{"role": "system",
|
35 |
+
"content": system_prompt},
|
36 |
+
{"role": "user", "content": text},
|
37 |
+
]
|
38 |
+
|
39 |
+
chat_completion = client.chat.completions.create(
|
40 |
+
messages=math_bot_messages,
|
41 |
+
model=model,
|
42 |
+
)
|
43 |
+
|
44 |
+
result = chat_completion.choices[0].message.content
|
45 |
+
return result
|
46 |
+
|
47 |
+
|
48 |
+
def extract_RSE_1(text):
|
49 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all spatial entities (directional keywords) from a given text. Spatial entities can include directional keywords such as north, south, east, west, and more specific terms like northeast, northwest, southeast, southwest, as well as terms indicating locations like center, central, downtown, and midtown. For each spatial entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The hotel is located in the downtown area of New York, just south of Central Park, with a beautiful view of the southeast corner."\n\nExpected Output:\n[###downtown###, ###south###, ###southeast###]'''
|
50 |
+
sent = 'The train station is situated in the central part of the city, just north of the river and east of the main square.'
|
51 |
+
|
52 |
+
math_bot_messages = [
|
53 |
+
{"role": "system",
|
54 |
+
"content": system_prompt},
|
55 |
+
{"role": "user", "content": text},
|
56 |
+
]
|
57 |
+
|
58 |
+
chat_completion = client.chat.completions.create(
|
59 |
+
messages=math_bot_messages,
|
60 |
+
model=model,
|
61 |
+
)
|
62 |
+
|
63 |
+
result = chat_completion.choices[0].message.content
|
64 |
+
return result
|
65 |
+
|
66 |
+
|
67 |
+
def extract_RSE_2(text):
|
68 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy spatial entities (keywords) from a given text. Fuzzy spatial keywords can include terms like nearby, near, vicinity, close, beside, next, adjacent, immediate, border, surrounding, neighbourhood, proximity, territory, locality, and similar terms. For each fuzzy spatial keyword, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located nearby the lake, with several cafes close to the walking paths, and a small garden adjacent to the main entrance."\n\nExpected Output:\n[###nearby###, ###close###, ###adjacent###]'''
|
69 |
+
sent = 'The village is situated in the vicinity of the mountain range, with a small river flowing beside the houses and several farms next to the road.'
|
70 |
+
|
71 |
+
math_bot_messages = [
|
72 |
+
{"role": "system",
|
73 |
+
"content": system_prompt},
|
74 |
+
{"role": "user", "content": text},
|
75 |
+
]
|
76 |
+
|
77 |
+
chat_completion = client.chat.completions.create(
|
78 |
+
messages=math_bot_messages,
|
79 |
+
model=model,
|
80 |
+
)
|
81 |
+
|
82 |
+
result = chat_completion.choices[0].message.content
|
83 |
+
return result
|
84 |
+
|
85 |
+
|
86 |
+
def extract_RSE_3(text):
|
87 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy distance keywords from a given text. Fuzzy distance keywords include numeric values followed by distance units such as kilometer, mile, meter, foot, inch, centimeter, and other related units. The distance units can be in different formats, such as km, m, mi, ft, yd, cm, mm, or even in full words like kilometer, mile, or inch. For each fuzzy distance keyword, wrap the entire expression (number and unit) in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located 3 km away from the city center, while the nearest supermarket is only 500 meters from here, and the lake is about 1 mile further down the road."\n\nExpected Output:\n[###3 km###, ###500 meters###, ###1 mile###]'''
|
88 |
+
sent = 'The school is located approximately 2 miles from the station, while the nearest bus stop is 200 meters away. The hiking trail is about 5 kilometers east of the town center.'
|
89 |
+
|
90 |
+
math_bot_messages = [
|
91 |
+
{"role": "system",
|
92 |
+
"content": system_prompt},
|
93 |
+
{"role": "user", "content": text},
|
94 |
+
]
|
95 |
+
|
96 |
+
chat_completion = client.chat.completions.create(
|
97 |
+
messages=math_bot_messages,
|
98 |
+
model=model,
|
99 |
+
)
|
100 |
+
|
101 |
+
result = chat_completion.choices[0].message.content
|
102 |
+
return result
|
103 |
+
|
104 |
+
|
105 |
+
def extract(respond):
|
106 |
+
sent = '[###2 miles###, ###200 meters###, ###5 kilometers###]'
|
107 |
+
result = re.sub(r'###(.*?)###', r'\1', respond)
|
108 |
+
# 将处理后的字符串转化为列表并返回
|
109 |
+
return result.strip('[]').split(', ')
|
110 |
+
|
111 |
+
|
112 |
+
|
113 |
+
print(extract('[###2 miles###, ###200 meters###, ###5 kilometers###]'))
|
114 |
+
print(extract_GPE('Between Burwood and Glebe.'))
|
GeoLLM/main.py
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import re
|
3 |
+
|
4 |
+
client = OpenAI(
|
5 |
+
api_key='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'
|
6 |
+
)
|
7 |
+
|
8 |
+
model = "gpt-3.5-turbo"
|
9 |
+
|
10 |
+
def extract_GPE(text):
|
11 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all geopolitical entities from a given text. Geopolitical entities can include countries, regions, cities, autonomous regions, or other administrative divisions. For each geopolitical entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
12 |
+
sent = 'Where is France?'
|
13 |
+
|
14 |
+
math_bot_messages = [
|
15 |
+
{"role": "system",
|
16 |
+
"content": system_prompt},
|
17 |
+
{"role": "user", "content": text},
|
18 |
+
]
|
19 |
+
|
20 |
+
chat_completion = client.chat.completions.create(
|
21 |
+
messages=math_bot_messages,
|
22 |
+
model=model,
|
23 |
+
)
|
24 |
+
|
25 |
+
result = chat_completion.choices[0].message.content
|
26 |
+
return result
|
27 |
+
|
28 |
+
|
29 |
+
def extract_LOC(text):
|
30 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all location entities (LOC) from a given text. Location entities can include physical locations such as landmarks, geographical features, mountains, rivers, oceans, and places, but do not include political or administrative divisions such as countries or cities (these are considered geopolitical entities). For each location entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
31 |
+
sent = 'The Grand Canyon is one of the most spectacular natural wonders in the world, located in the state of Arizona. Nearby, the Colorado River flows through the canyon, carving its way through the rugged terrain. In the north, the Rocky Mountains stretch across several states, including Colorado and Wyoming.'
|
32 |
+
|
33 |
+
math_bot_messages = [
|
34 |
+
{"role": "system",
|
35 |
+
"content": system_prompt},
|
36 |
+
{"role": "user", "content": text},
|
37 |
+
]
|
38 |
+
|
39 |
+
chat_completion = client.chat.completions.create(
|
40 |
+
messages=math_bot_messages,
|
41 |
+
model=model,
|
42 |
+
)
|
43 |
+
|
44 |
+
result = chat_completion.choices[0].message.content
|
45 |
+
return result
|
46 |
+
|
47 |
+
|
48 |
+
def extract_RSE_1(text):
|
49 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all spatial entities (directional keywords) from a given text. Spatial entities can include directional keywords such as north, south, east, west, and more specific terms like northeast, northwest, southeast, southwest, as well as terms indicating locations like center, central, downtown, and midtown. For each spatial entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The hotel is located in the downtown area of New York, just south of Central Park, with a beautiful view of the southeast corner."\n\nExpected Output:\n[###downtown###, ###south###, ###southeast###]'''
|
50 |
+
sent = 'The train station is situated in the central part of the city, just north of the river and east of the main square.'
|
51 |
+
|
52 |
+
math_bot_messages = [
|
53 |
+
{"role": "system",
|
54 |
+
"content": system_prompt},
|
55 |
+
{"role": "user", "content": text},
|
56 |
+
]
|
57 |
+
|
58 |
+
chat_completion = client.chat.completions.create(
|
59 |
+
messages=math_bot_messages,
|
60 |
+
model=model,
|
61 |
+
)
|
62 |
+
|
63 |
+
result = chat_completion.choices[0].message.content
|
64 |
+
return result
|
65 |
+
|
66 |
+
|
67 |
+
def extract_RSE_2(text):
|
68 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy spatial entities (keywords) from a given text. Fuzzy spatial keywords can include terms like nearby, near, vicinity, close, beside, next, adjacent, immediate, border, surrounding, neighbourhood, proximity, territory, locality, and similar terms. For each fuzzy spatial keyword, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located nearby the lake, with several cafes close to the walking paths, and a small garden adjacent to the main entrance."\n\nExpected Output:\n[###nearby###, ###close###, ###adjacent###]'''
|
69 |
+
sent = 'The village is situated in the vicinity of the mountain range, with a small river flowing beside the houses and several farms next to the road.'
|
70 |
+
|
71 |
+
math_bot_messages = [
|
72 |
+
{"role": "system",
|
73 |
+
"content": system_prompt},
|
74 |
+
{"role": "user", "content": text},
|
75 |
+
]
|
76 |
+
|
77 |
+
chat_completion = client.chat.completions.create(
|
78 |
+
messages=math_bot_messages,
|
79 |
+
model=model,
|
80 |
+
)
|
81 |
+
|
82 |
+
result = chat_completion.choices[0].message.content
|
83 |
+
return result
|
84 |
+
|
85 |
+
|
86 |
+
def extract_RSE_3(text):
|
87 |
+
system_prompt = '''You are a professional geographer. Your task is to extract all fuzzy distance keywords from a given text. Fuzzy distance keywords include numeric values followed by distance units such as kilometer, mile, meter, foot, inch, centimeter, and other related units. The distance units can be in different formats, such as km, m, mi, ft, yd, cm, mm, or even in full words like kilometer, mile, or inch. For each fuzzy distance keyword, wrap the entire expression (number and unit) in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"The park is located 3 km away from the city center, while the nearest supermarket is only 500 meters from here, and the lake is about 1 mile further down the road."\n\nExpected Output:\n[###3 km###, ###500 meters###, ###1 mile###]'''
|
88 |
+
sent = 'The school is located approximately 2 miles from the station, while the nearest bus stop is 200 meters away. The hiking trail is about 5 kilometers east of the town center.'
|
89 |
+
|
90 |
+
math_bot_messages = [
|
91 |
+
{"role": "system",
|
92 |
+
"content": system_prompt},
|
93 |
+
{"role": "user", "content": text},
|
94 |
+
]
|
95 |
+
|
96 |
+
chat_completion = client.chat.completions.create(
|
97 |
+
messages=math_bot_messages,
|
98 |
+
model=model,
|
99 |
+
)
|
100 |
+
|
101 |
+
result = chat_completion.choices[0].message.content
|
102 |
+
return result
|
103 |
+
|
104 |
+
|
105 |
+
def extract(respond):
|
106 |
+
sent = '[###2 miles###, ###200 meters###, ###5 kilometers###]'
|
107 |
+
result = re.sub(r'###(.*?)###', r'\1', respond)
|
108 |
+
# 将处理后的字符串转化为列表并返回
|
109 |
+
return result.strip('[]').split(', ')
|
110 |
+
|
111 |
+
|
112 |
+
print(extract('[###2 miles###, ###200 meters###, ###5 kilometers###]'))
|
GeoLLM/test.py
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# from openai import OpenAI
|
2 |
+
#
|
3 |
+
#
|
4 |
+
# client = OpenAI(
|
5 |
+
# api_key='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'
|
6 |
+
# )
|
7 |
+
#
|
8 |
+
# system_prompt = '''You are a professional geographer. Your task is to extract all geopolitical entities from a given text. Geopolitical entities can include countries, regions, cities, autonomous regions, or other administrative divisions. For each geopolitical entity, wrap the name in a unique character sequence, such as [###ENTITY###]. If there are multiple entities, output them in the following format:\n[###ENTITY1###, ###ENTITY2###, ###ENTITY3###]\nHere is an example:\n Example:\n\nText:\n"China and India are two of the most populous countries in Asia."\n\nExpected Output:\n[###China###, ###India###]'''
|
9 |
+
# sent = 'Where is France?'
|
10 |
+
#
|
11 |
+
# math_bot_messages = [
|
12 |
+
# {"role": "system",
|
13 |
+
# "content": system_prompt},
|
14 |
+
# {"role": "user", "content": sent},
|
15 |
+
# ]
|
16 |
+
#
|
17 |
+
# chat_completion = client.chat.completions.create(
|
18 |
+
# messages=math_bot_messages,
|
19 |
+
# model="gpt-3.5-turbo",
|
20 |
+
# )
|
21 |
+
#
|
22 |
+
# result = chat_completion.choices[0].message.content
|
23 |
+
#
|
24 |
+
#
|
25 |
+
# print(result)
|
26 |
+
#
|
27 |
+
#
|
28 |
+
import ../reregex_spatial
|
29 |
+
|
30 |
+
|
31 |
+
regex_spatial.get_level1_regex()
|
LICENSE
ADDED
@@ -0,0 +1,674 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 3, 29 June 2007
|
3 |
+
|
4 |
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
5 |
+
Everyone is permitted to copy and distribute verbatim copies
|
6 |
+
of this license document, but changing it is not allowed.
|
7 |
+
|
8 |
+
Preamble
|
9 |
+
|
10 |
+
The GNU General Public License is a free, copyleft license for
|
11 |
+
software and other kinds of works.
|
12 |
+
|
13 |
+
The licenses for most software and other practical works are designed
|
14 |
+
to take away your freedom to share and change the works. By contrast,
|
15 |
+
the GNU General Public License is intended to guarantee your freedom to
|
16 |
+
share and change all versions of a program--to make sure it remains free
|
17 |
+
software for all its users. We, the Free Software Foundation, use the
|
18 |
+
GNU General Public License for most of our software; it applies also to
|
19 |
+
any other work released this way by its authors. You can apply it to
|
20 |
+
your programs, too.
|
21 |
+
|
22 |
+
When we speak of free software, we are referring to freedom, not
|
23 |
+
price. Our General Public Licenses are designed to make sure that you
|
24 |
+
have the freedom to distribute copies of free software (and charge for
|
25 |
+
them if you wish), that you receive source code or can get it if you
|
26 |
+
want it, that you can change the software or use pieces of it in new
|
27 |
+
free programs, and that you know you can do these things.
|
28 |
+
|
29 |
+
To protect your rights, we need to prevent others from denying you
|
30 |
+
these rights or asking you to surrender the rights. Therefore, you have
|
31 |
+
certain responsibilities if you distribute copies of the software, or if
|
32 |
+
you modify it: responsibilities to respect the freedom of others.
|
33 |
+
|
34 |
+
For example, if you distribute copies of such a program, whether
|
35 |
+
gratis or for a fee, you must pass on to the recipients the same
|
36 |
+
freedoms that you received. You must make sure that they, too, receive
|
37 |
+
or can get the source code. And you must show them these terms so they
|
38 |
+
know their rights.
|
39 |
+
|
40 |
+
Developers that use the GNU GPL protect your rights with two steps:
|
41 |
+
(1) assert copyright on the software, and (2) offer you this License
|
42 |
+
giving you legal permission to copy, distribute and/or modify it.
|
43 |
+
|
44 |
+
For the developers' and authors' protection, the GPL clearly explains
|
45 |
+
that there is no warranty for this free software. For both users' and
|
46 |
+
authors' sake, the GPL requires that modified versions be marked as
|
47 |
+
changed, so that their problems will not be attributed erroneously to
|
48 |
+
authors of previous versions.
|
49 |
+
|
50 |
+
Some devices are designed to deny users access to install or run
|
51 |
+
modified versions of the software inside them, although the manufacturer
|
52 |
+
can do so. This is fundamentally incompatible with the aim of
|
53 |
+
protecting users' freedom to change the software. The systematic
|
54 |
+
pattern of such abuse occurs in the area of products for individuals to
|
55 |
+
use, which is precisely where it is most unacceptable. Therefore, we
|
56 |
+
have designed this version of the GPL to prohibit the practice for those
|
57 |
+
products. If such problems arise substantially in other domains, we
|
58 |
+
stand ready to extend this provision to those domains in future versions
|
59 |
+
of the GPL, as needed to protect the freedom of users.
|
60 |
+
|
61 |
+
Finally, every program is threatened constantly by software patents.
|
62 |
+
States should not allow patents to restrict development and use of
|
63 |
+
software on general-purpose computers, but in those that do, we wish to
|
64 |
+
avoid the special danger that patents applied to a free program could
|
65 |
+
make it effectively proprietary. To prevent this, the GPL assures that
|
66 |
+
patents cannot be used to render the program non-free.
|
67 |
+
|
68 |
+
The precise terms and conditions for copying, distribution and
|
69 |
+
modification follow.
|
70 |
+
|
71 |
+
TERMS AND CONDITIONS
|
72 |
+
|
73 |
+
0. Definitions.
|
74 |
+
|
75 |
+
"This License" refers to version 3 of the GNU General Public License.
|
76 |
+
|
77 |
+
"Copyright" also means copyright-like laws that apply to other kinds of
|
78 |
+
works, such as semiconductor masks.
|
79 |
+
|
80 |
+
"The Program" refers to any copyrightable work licensed under this
|
81 |
+
License. Each licensee is addressed as "you". "Licensees" and
|
82 |
+
"recipients" may be individuals or organizations.
|
83 |
+
|
84 |
+
To "modify" a work means to copy from or adapt all or part of the work
|
85 |
+
in a fashion requiring copyright permission, other than the making of an
|
86 |
+
exact copy. The resulting work is called a "modified version" of the
|
87 |
+
earlier work or a work "based on" the earlier work.
|
88 |
+
|
89 |
+
A "covered work" means either the unmodified Program or a work based
|
90 |
+
on the Program.
|
91 |
+
|
92 |
+
To "propagate" a work means to do anything with it that, without
|
93 |
+
permission, would make you directly or secondarily liable for
|
94 |
+
infringement under applicable copyright law, except executing it on a
|
95 |
+
computer or modifying a private copy. Propagation includes copying,
|
96 |
+
distribution (with or without modification), making available to the
|
97 |
+
public, and in some countries other activities as well.
|
98 |
+
|
99 |
+
To "convey" a work means any kind of propagation that enables other
|
100 |
+
parties to make or receive copies. Mere interaction with a user through
|
101 |
+
a computer network, with no transfer of a copy, is not conveying.
|
102 |
+
|
103 |
+
An interactive user interface displays "Appropriate Legal Notices"
|
104 |
+
to the extent that it includes a convenient and prominently visible
|
105 |
+
feature that (1) displays an appropriate copyright notice, and (2)
|
106 |
+
tells the user that there is no warranty for the work (except to the
|
107 |
+
extent that warranties are provided), that licensees may convey the
|
108 |
+
work under this License, and how to view a copy of this License. If
|
109 |
+
the interface presents a list of user commands or options, such as a
|
110 |
+
menu, a prominent item in the list meets this criterion.
|
111 |
+
|
112 |
+
1. Source Code.
|
113 |
+
|
114 |
+
The "source code" for a work means the preferred form of the work
|
115 |
+
for making modifications to it. "Object code" means any non-source
|
116 |
+
form of a work.
|
117 |
+
|
118 |
+
A "Standard Interface" means an interface that either is an official
|
119 |
+
standard defined by a recognized standards body, or, in the case of
|
120 |
+
interfaces specified for a particular programming language, one that
|
121 |
+
is widely used among developers working in that language.
|
122 |
+
|
123 |
+
The "System Libraries" of an executable work include anything, other
|
124 |
+
than the work as a whole, that (a) is included in the normal form of
|
125 |
+
packaging a Major Component, but which is not part of that Major
|
126 |
+
Component, and (b) serves only to enable use of the work with that
|
127 |
+
Major Component, or to implement a Standard Interface for which an
|
128 |
+
implementation is available to the public in source code form. A
|
129 |
+
"Major Component", in this context, means a major essential component
|
130 |
+
(kernel, window system, and so on) of the specific operating system
|
131 |
+
(if any) on which the executable work runs, or a compiler used to
|
132 |
+
produce the work, or an object code interpreter used to run it.
|
133 |
+
|
134 |
+
The "Corresponding Source" for a work in object code form means all
|
135 |
+
the source code needed to generate, install, and (for an executable
|
136 |
+
work) run the object code and to modify the work, including scripts to
|
137 |
+
control those activities. However, it does not include the work's
|
138 |
+
System Libraries, or general-purpose tools or generally available free
|
139 |
+
programs which are used unmodified in performing those activities but
|
140 |
+
which are not part of the work. For example, Corresponding Source
|
141 |
+
includes interface definition files associated with source files for
|
142 |
+
the work, and the source code for shared libraries and dynamically
|
143 |
+
linked subprograms that the work is specifically designed to require,
|
144 |
+
such as by intimate data communication or control flow between those
|
145 |
+
subprograms and other parts of the work.
|
146 |
+
|
147 |
+
The Corresponding Source need not include anything that users
|
148 |
+
can regenerate automatically from other parts of the Corresponding
|
149 |
+
Source.
|
150 |
+
|
151 |
+
The Corresponding Source for a work in source code form is that
|
152 |
+
same work.
|
153 |
+
|
154 |
+
2. Basic Permissions.
|
155 |
+
|
156 |
+
All rights granted under this License are granted for the term of
|
157 |
+
copyright on the Program, and are irrevocable provided the stated
|
158 |
+
conditions are met. This License explicitly affirms your unlimited
|
159 |
+
permission to run the unmodified Program. The output from running a
|
160 |
+
covered work is covered by this License only if the output, given its
|
161 |
+
content, constitutes a covered work. This License acknowledges your
|
162 |
+
rights of fair use or other equivalent, as provided by copyright law.
|
163 |
+
|
164 |
+
You may make, run and propagate covered works that you do not
|
165 |
+
convey, without conditions so long as your license otherwise remains
|
166 |
+
in force. You may convey covered works to others for the sole purpose
|
167 |
+
of having them make modifications exclusively for you, or provide you
|
168 |
+
with facilities for running those works, provided that you comply with
|
169 |
+
the terms of this License in conveying all material for which you do
|
170 |
+
not control copyright. Those thus making or running the covered works
|
171 |
+
for you must do so exclusively on your behalf, under your direction
|
172 |
+
and control, on terms that prohibit them from making any copies of
|
173 |
+
your copyrighted material outside their relationship with you.
|
174 |
+
|
175 |
+
Conveying under any other circumstances is permitted solely under
|
176 |
+
the conditions stated below. Sublicensing is not allowed; section 10
|
177 |
+
makes it unnecessary.
|
178 |
+
|
179 |
+
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
180 |
+
|
181 |
+
No covered work shall be deemed part of an effective technological
|
182 |
+
measure under any applicable law fulfilling obligations under article
|
183 |
+
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
184 |
+
similar laws prohibiting or restricting circumvention of such
|
185 |
+
measures.
|
186 |
+
|
187 |
+
When you convey a covered work, you waive any legal power to forbid
|
188 |
+
circumvention of technological measures to the extent such circumvention
|
189 |
+
is effected by exercising rights under this License with respect to
|
190 |
+
the covered work, and you disclaim any intention to limit operation or
|
191 |
+
modification of the work as a means of enforcing, against the work's
|
192 |
+
users, your or third parties' legal rights to forbid circumvention of
|
193 |
+
technological measures.
|
194 |
+
|
195 |
+
4. Conveying Verbatim Copies.
|
196 |
+
|
197 |
+
You may convey verbatim copies of the Program's source code as you
|
198 |
+
receive it, in any medium, provided that you conspicuously and
|
199 |
+
appropriately publish on each copy an appropriate copyright notice;
|
200 |
+
keep intact all notices stating that this License and any
|
201 |
+
non-permissive terms added in accord with section 7 apply to the code;
|
202 |
+
keep intact all notices of the absence of any warranty; and give all
|
203 |
+
recipients a copy of this License along with the Program.
|
204 |
+
|
205 |
+
You may charge any price or no price for each copy that you convey,
|
206 |
+
and you may offer support or warranty protection for a fee.
|
207 |
+
|
208 |
+
5. Conveying Modified Source Versions.
|
209 |
+
|
210 |
+
You may convey a work based on the Program, or the modifications to
|
211 |
+
produce it from the Program, in the form of source code under the
|
212 |
+
terms of section 4, provided that you also meet all of these conditions:
|
213 |
+
|
214 |
+
a) The work must carry prominent notices stating that you modified
|
215 |
+
it, and giving a relevant date.
|
216 |
+
|
217 |
+
b) The work must carry prominent notices stating that it is
|
218 |
+
released under this License and any conditions added under section
|
219 |
+
7. This requirement modifies the requirement in section 4 to
|
220 |
+
"keep intact all notices".
|
221 |
+
|
222 |
+
c) You must license the entire work, as a whole, under this
|
223 |
+
License to anyone who comes into possession of a copy. This
|
224 |
+
License will therefore apply, along with any applicable section 7
|
225 |
+
additional terms, to the whole of the work, and all its parts,
|
226 |
+
regardless of how they are packaged. This License gives no
|
227 |
+
permission to license the work in any other way, but it does not
|
228 |
+
invalidate such permission if you have separately received it.
|
229 |
+
|
230 |
+
d) If the work has interactive user interfaces, each must display
|
231 |
+
Appropriate Legal Notices; however, if the Program has interactive
|
232 |
+
interfaces that do not display Appropriate Legal Notices, your
|
233 |
+
work need not make them do so.
|
234 |
+
|
235 |
+
A compilation of a covered work with other separate and independent
|
236 |
+
works, which are not by their nature extensions of the covered work,
|
237 |
+
and which are not combined with it such as to form a larger program,
|
238 |
+
in or on a volume of a storage or distribution medium, is called an
|
239 |
+
"aggregate" if the compilation and its resulting copyright are not
|
240 |
+
used to limit the access or legal rights of the compilation's users
|
241 |
+
beyond what the individual works permit. Inclusion of a covered work
|
242 |
+
in an aggregate does not cause this License to apply to the other
|
243 |
+
parts of the aggregate.
|
244 |
+
|
245 |
+
6. Conveying Non-Source Forms.
|
246 |
+
|
247 |
+
You may convey a covered work in object code form under the terms
|
248 |
+
of sections 4 and 5, provided that you also convey the
|
249 |
+
machine-readable Corresponding Source under the terms of this License,
|
250 |
+
in one of these ways:
|
251 |
+
|
252 |
+
a) Convey the object code in, or embodied in, a physical product
|
253 |
+
(including a physical distribution medium), accompanied by the
|
254 |
+
Corresponding Source fixed on a durable physical medium
|
255 |
+
customarily used for software interchange.
|
256 |
+
|
257 |
+
b) Convey the object code in, or embodied in, a physical product
|
258 |
+
(including a physical distribution medium), accompanied by a
|
259 |
+
written offer, valid for at least three years and valid for as
|
260 |
+
long as you offer spare parts or customer support for that product
|
261 |
+
model, to give anyone who possesses the object code either (1) a
|
262 |
+
copy of the Corresponding Source for all the software in the
|
263 |
+
product that is covered by this License, on a durable physical
|
264 |
+
medium customarily used for software interchange, for a price no
|
265 |
+
more than your reasonable cost of physically performing this
|
266 |
+
conveying of source, or (2) access to copy the
|
267 |
+
Corresponding Source from a network server at no charge.
|
268 |
+
|
269 |
+
c) Convey individual copies of the object code with a copy of the
|
270 |
+
written offer to provide the Corresponding Source. This
|
271 |
+
alternative is allowed only occasionally and noncommercially, and
|
272 |
+
only if you received the object code with such an offer, in accord
|
273 |
+
with subsection 6b.
|
274 |
+
|
275 |
+
d) Convey the object code by offering access from a designated
|
276 |
+
place (gratis or for a charge), and offer equivalent access to the
|
277 |
+
Corresponding Source in the same way through the same place at no
|
278 |
+
further charge. You need not require recipients to copy the
|
279 |
+
Corresponding Source along with the object code. If the place to
|
280 |
+
copy the object code is a network server, the Corresponding Source
|
281 |
+
may be on a different server (operated by you or a third party)
|
282 |
+
that supports equivalent copying facilities, provided you maintain
|
283 |
+
clear directions next to the object code saying where to find the
|
284 |
+
Corresponding Source. Regardless of what server hosts the
|
285 |
+
Corresponding Source, you remain obligated to ensure that it is
|
286 |
+
available for as long as needed to satisfy these requirements.
|
287 |
+
|
288 |
+
e) Convey the object code using peer-to-peer transmission, provided
|
289 |
+
you inform other peers where the object code and Corresponding
|
290 |
+
Source of the work are being offered to the general public at no
|
291 |
+
charge under subsection 6d.
|
292 |
+
|
293 |
+
A separable portion of the object code, whose source code is excluded
|
294 |
+
from the Corresponding Source as a System Library, need not be
|
295 |
+
included in conveying the object code work.
|
296 |
+
|
297 |
+
A "User Product" is either (1) a "consumer product", which means any
|
298 |
+
tangible personal property which is normally used for personal, family,
|
299 |
+
or household purposes, or (2) anything designed or sold for incorporation
|
300 |
+
into a dwelling. In determining whether a product is a consumer product,
|
301 |
+
doubtful cases shall be resolved in favor of coverage. For a particular
|
302 |
+
product received by a particular user, "normally used" refers to a
|
303 |
+
typical or common use of that class of product, regardless of the status
|
304 |
+
of the particular user or of the way in which the particular user
|
305 |
+
actually uses, or expects or is expected to use, the product. A product
|
306 |
+
is a consumer product regardless of whether the product has substantial
|
307 |
+
commercial, industrial or non-consumer uses, unless such uses represent
|
308 |
+
the only significant mode of use of the product.
|
309 |
+
|
310 |
+
"Installation Information" for a User Product means any methods,
|
311 |
+
procedures, authorization keys, or other information required to install
|
312 |
+
and execute modified versions of a covered work in that User Product from
|
313 |
+
a modified version of its Corresponding Source. The information must
|
314 |
+
suffice to ensure that the continued functioning of the modified object
|
315 |
+
code is in no case prevented or interfered with solely because
|
316 |
+
modification has been made.
|
317 |
+
|
318 |
+
If you convey an object code work under this section in, or with, or
|
319 |
+
specifically for use in, a User Product, and the conveying occurs as
|
320 |
+
part of a transaction in which the right of possession and use of the
|
321 |
+
User Product is transferred to the recipient in perpetuity or for a
|
322 |
+
fixed term (regardless of how the transaction is characterized), the
|
323 |
+
Corresponding Source conveyed under this section must be accompanied
|
324 |
+
by the Installation Information. But this requirement does not apply
|
325 |
+
if neither you nor any third party retains the ability to install
|
326 |
+
modified object code on the User Product (for example, the work has
|
327 |
+
been installed in ROM).
|
328 |
+
|
329 |
+
The requirement to provide Installation Information does not include a
|
330 |
+
requirement to continue to provide support service, warranty, or updates
|
331 |
+
for a work that has been modified or installed by the recipient, or for
|
332 |
+
the User Product in which it has been modified or installed. Access to a
|
333 |
+
network may be denied when the modification itself materially and
|
334 |
+
adversely affects the operation of the network or violates the rules and
|
335 |
+
protocols for communication across the network.
|
336 |
+
|
337 |
+
Corresponding Source conveyed, and Installation Information provided,
|
338 |
+
in accord with this section must be in a format that is publicly
|
339 |
+
documented (and with an implementation available to the public in
|
340 |
+
source code form), and must require no special password or key for
|
341 |
+
unpacking, reading or copying.
|
342 |
+
|
343 |
+
7. Additional Terms.
|
344 |
+
|
345 |
+
"Additional permissions" are terms that supplement the terms of this
|
346 |
+
License by making exceptions from one or more of its conditions.
|
347 |
+
Additional permissions that are applicable to the entire Program shall
|
348 |
+
be treated as though they were included in this License, to the extent
|
349 |
+
that they are valid under applicable law. If additional permissions
|
350 |
+
apply only to part of the Program, that part may be used separately
|
351 |
+
under those permissions, but the entire Program remains governed by
|
352 |
+
this License without regard to the additional permissions.
|
353 |
+
|
354 |
+
When you convey a copy of a covered work, you may at your option
|
355 |
+
remove any additional permissions from that copy, or from any part of
|
356 |
+
it. (Additional permissions may be written to require their own
|
357 |
+
removal in certain cases when you modify the work.) You may place
|
358 |
+
additional permissions on material, added by you to a covered work,
|
359 |
+
for which you have or can give appropriate copyright permission.
|
360 |
+
|
361 |
+
Notwithstanding any other provision of this License, for material you
|
362 |
+
add to a covered work, you may (if authorized by the copyright holders of
|
363 |
+
that material) supplement the terms of this License with terms:
|
364 |
+
|
365 |
+
a) Disclaiming warranty or limiting liability differently from the
|
366 |
+
terms of sections 15 and 16 of this License; or
|
367 |
+
|
368 |
+
b) Requiring preservation of specified reasonable legal notices or
|
369 |
+
author attributions in that material or in the Appropriate Legal
|
370 |
+
Notices displayed by works containing it; or
|
371 |
+
|
372 |
+
c) Prohibiting misrepresentation of the origin of that material, or
|
373 |
+
requiring that modified versions of such material be marked in
|
374 |
+
reasonable ways as different from the original version; or
|
375 |
+
|
376 |
+
d) Limiting the use for publicity purposes of names of licensors or
|
377 |
+
authors of the material; or
|
378 |
+
|
379 |
+
e) Declining to grant rights under trademark law for use of some
|
380 |
+
trade names, trademarks, or service marks; or
|
381 |
+
|
382 |
+
f) Requiring indemnification of licensors and authors of that
|
383 |
+
material by anyone who conveys the material (or modified versions of
|
384 |
+
it) with contractual assumptions of liability to the recipient, for
|
385 |
+
any liability that these contractual assumptions directly impose on
|
386 |
+
those licensors and authors.
|
387 |
+
|
388 |
+
All other non-permissive additional terms are considered "further
|
389 |
+
restrictions" within the meaning of section 10. If the Program as you
|
390 |
+
received it, or any part of it, contains a notice stating that it is
|
391 |
+
governed by this License along with a term that is a further
|
392 |
+
restriction, you may remove that term. If a license document contains
|
393 |
+
a further restriction but permits relicensing or conveying under this
|
394 |
+
License, you may add to a covered work material governed by the terms
|
395 |
+
of that license document, provided that the further restriction does
|
396 |
+
not survive such relicensing or conveying.
|
397 |
+
|
398 |
+
If you add terms to a covered work in accord with this section, you
|
399 |
+
must place, in the relevant source files, a statement of the
|
400 |
+
additional terms that apply to those files, or a notice indicating
|
401 |
+
where to find the applicable terms.
|
402 |
+
|
403 |
+
Additional terms, permissive or non-permissive, may be stated in the
|
404 |
+
form of a separately written license, or stated as exceptions;
|
405 |
+
the above requirements apply either way.
|
406 |
+
|
407 |
+
8. Termination.
|
408 |
+
|
409 |
+
You may not propagate or modify a covered work except as expressly
|
410 |
+
provided under this License. Any attempt otherwise to propagate or
|
411 |
+
modify it is void, and will automatically terminate your rights under
|
412 |
+
this License (including any patent licenses granted under the third
|
413 |
+
paragraph of section 11).
|
414 |
+
|
415 |
+
However, if you cease all violation of this License, then your
|
416 |
+
license from a particular copyright holder is reinstated (a)
|
417 |
+
provisionally, unless and until the copyright holder explicitly and
|
418 |
+
finally terminates your license, and (b) permanently, if the copyright
|
419 |
+
holder fails to notify you of the violation by some reasonable means
|
420 |
+
prior to 60 days after the cessation.
|
421 |
+
|
422 |
+
Moreover, your license from a particular copyright holder is
|
423 |
+
reinstated permanently if the copyright holder notifies you of the
|
424 |
+
violation by some reasonable means, this is the first time you have
|
425 |
+
received notice of violation of this License (for any work) from that
|
426 |
+
copyright holder, and you cure the violation prior to 30 days after
|
427 |
+
your receipt of the notice.
|
428 |
+
|
429 |
+
Termination of your rights under this section does not terminate the
|
430 |
+
licenses of parties who have received copies or rights from you under
|
431 |
+
this License. If your rights have been terminated and not permanently
|
432 |
+
reinstated, you do not qualify to receive new licenses for the same
|
433 |
+
material under section 10.
|
434 |
+
|
435 |
+
9. Acceptance Not Required for Having Copies.
|
436 |
+
|
437 |
+
You are not required to accept this License in order to receive or
|
438 |
+
run a copy of the Program. Ancillary propagation of a covered work
|
439 |
+
occurring solely as a consequence of using peer-to-peer transmission
|
440 |
+
to receive a copy likewise does not require acceptance. However,
|
441 |
+
nothing other than this License grants you permission to propagate or
|
442 |
+
modify any covered work. These actions infringe copyright if you do
|
443 |
+
not accept this License. Therefore, by modifying or propagating a
|
444 |
+
covered work, you indicate your acceptance of this License to do so.
|
445 |
+
|
446 |
+
10. Automatic Licensing of Downstream Recipients.
|
447 |
+
|
448 |
+
Each time you convey a covered work, the recipient automatically
|
449 |
+
receives a license from the original licensors, to run, modify and
|
450 |
+
propagate that work, subject to this License. You are not responsible
|
451 |
+
for enforcing compliance by third parties with this License.
|
452 |
+
|
453 |
+
An "entity transaction" is a transaction transferring control of an
|
454 |
+
organization, or substantially all assets of one, or subdividing an
|
455 |
+
organization, or merging organizations. If propagation of a covered
|
456 |
+
work results from an entity transaction, each party to that
|
457 |
+
transaction who receives a copy of the work also receives whatever
|
458 |
+
licenses to the work the party's predecessor in interest had or could
|
459 |
+
give under the previous paragraph, plus a right to possession of the
|
460 |
+
Corresponding Source of the work from the predecessor in interest, if
|
461 |
+
the predecessor has it or can get it with reasonable efforts.
|
462 |
+
|
463 |
+
You may not impose any further restrictions on the exercise of the
|
464 |
+
rights granted or affirmed under this License. For example, you may
|
465 |
+
not impose a license fee, royalty, or other charge for exercise of
|
466 |
+
rights granted under this License, and you may not initiate litigation
|
467 |
+
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
468 |
+
any patent claim is infringed by making, using, selling, offering for
|
469 |
+
sale, or importing the Program or any portion of it.
|
470 |
+
|
471 |
+
11. Patents.
|
472 |
+
|
473 |
+
A "contributor" is a copyright holder who authorizes use under this
|
474 |
+
License of the Program or a work on which the Program is based. The
|
475 |
+
work thus licensed is called the contributor's "contributor version".
|
476 |
+
|
477 |
+
A contributor's "essential patent claims" are all patent claims
|
478 |
+
owned or controlled by the contributor, whether already acquired or
|
479 |
+
hereafter acquired, that would be infringed by some manner, permitted
|
480 |
+
by this License, of making, using, or selling its contributor version,
|
481 |
+
but do not include claims that would be infringed only as a
|
482 |
+
consequence of further modification of the contributor version. For
|
483 |
+
purposes of this definition, "control" includes the right to grant
|
484 |
+
patent sublicenses in a manner consistent with the requirements of
|
485 |
+
this License.
|
486 |
+
|
487 |
+
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
488 |
+
patent license under the contributor's essential patent claims, to
|
489 |
+
make, use, sell, offer for sale, import and otherwise run, modify and
|
490 |
+
propagate the contents of its contributor version.
|
491 |
+
|
492 |
+
In the following three paragraphs, a "patent license" is any express
|
493 |
+
agreement or commitment, however denominated, not to enforce a patent
|
494 |
+
(such as an express permission to practice a patent or covenant not to
|
495 |
+
sue for patent infringement). To "grant" such a patent license to a
|
496 |
+
party means to make such an agreement or commitment not to enforce a
|
497 |
+
patent against the party.
|
498 |
+
|
499 |
+
If you convey a covered work, knowingly relying on a patent license,
|
500 |
+
and the Corresponding Source of the work is not available for anyone
|
501 |
+
to copy, free of charge and under the terms of this License, through a
|
502 |
+
publicly available network server or other readily accessible means,
|
503 |
+
then you must either (1) cause the Corresponding Source to be so
|
504 |
+
available, or (2) arrange to deprive yourself of the benefit of the
|
505 |
+
patent license for this particular work, or (3) arrange, in a manner
|
506 |
+
consistent with the requirements of this License, to extend the patent
|
507 |
+
license to downstream recipients. "Knowingly relying" means you have
|
508 |
+
actual knowledge that, but for the patent license, your conveying the
|
509 |
+
covered work in a country, or your recipient's use of the covered work
|
510 |
+
in a country, would infringe one or more identifiable patents in that
|
511 |
+
country that you have reason to believe are valid.
|
512 |
+
|
513 |
+
If, pursuant to or in connection with a single transaction or
|
514 |
+
arrangement, you convey, or propagate by procuring conveyance of, a
|
515 |
+
covered work, and grant a patent license to some of the parties
|
516 |
+
receiving the covered work authorizing them to use, propagate, modify
|
517 |
+
or convey a specific copy of the covered work, then the patent license
|
518 |
+
you grant is automatically extended to all recipients of the covered
|
519 |
+
work and works based on it.
|
520 |
+
|
521 |
+
A patent license is "discriminatory" if it does not include within
|
522 |
+
the scope of its coverage, prohibits the exercise of, or is
|
523 |
+
conditioned on the non-exercise of one or more of the rights that are
|
524 |
+
specifically granted under this License. You may not convey a covered
|
525 |
+
work if you are a party to an arrangement with a third party that is
|
526 |
+
in the business of distributing software, under which you make payment
|
527 |
+
to the third party based on the extent of your activity of conveying
|
528 |
+
the work, and under which the third party grants, to any of the
|
529 |
+
parties who would receive the covered work from you, a discriminatory
|
530 |
+
patent license (a) in connection with copies of the covered work
|
531 |
+
conveyed by you (or copies made from those copies), or (b) primarily
|
532 |
+
for and in connection with specific products or compilations that
|
533 |
+
contain the covered work, unless you entered into that arrangement,
|
534 |
+
or that patent license was granted, prior to 28 March 2007.
|
535 |
+
|
536 |
+
Nothing in this License shall be construed as excluding or limiting
|
537 |
+
any implied license or other defenses to infringement that may
|
538 |
+
otherwise be available to you under applicable patent law.
|
539 |
+
|
540 |
+
12. No Surrender of Others' Freedom.
|
541 |
+
|
542 |
+
If conditions are imposed on you (whether by court order, agreement or
|
543 |
+
otherwise) that contradict the conditions of this License, they do not
|
544 |
+
excuse you from the conditions of this License. If you cannot convey a
|
545 |
+
covered work so as to satisfy simultaneously your obligations under this
|
546 |
+
License and any other pertinent obligations, then as a consequence you may
|
547 |
+
not convey it at all. For example, if you agree to terms that obligate you
|
548 |
+
to collect a royalty for further conveying from those to whom you convey
|
549 |
+
the Program, the only way you could satisfy both those terms and this
|
550 |
+
License would be to refrain entirely from conveying the Program.
|
551 |
+
|
552 |
+
13. Use with the GNU Affero General Public License.
|
553 |
+
|
554 |
+
Notwithstanding any other provision of this License, you have
|
555 |
+
permission to link or combine any covered work with a work licensed
|
556 |
+
under version 3 of the GNU Affero General Public License into a single
|
557 |
+
combined work, and to convey the resulting work. The terms of this
|
558 |
+
License will continue to apply to the part which is the covered work,
|
559 |
+
but the special requirements of the GNU Affero General Public License,
|
560 |
+
section 13, concerning interaction through a network will apply to the
|
561 |
+
combination as such.
|
562 |
+
|
563 |
+
14. Revised Versions of this License.
|
564 |
+
|
565 |
+
The Free Software Foundation may publish revised and/or new versions of
|
566 |
+
the GNU General Public License from time to time. Such new versions will
|
567 |
+
be similar in spirit to the present version, but may differ in detail to
|
568 |
+
address new problems or concerns.
|
569 |
+
|
570 |
+
Each version is given a distinguishing version number. If the
|
571 |
+
Program specifies that a certain numbered version of the GNU General
|
572 |
+
Public License "or any later version" applies to it, you have the
|
573 |
+
option of following the terms and conditions either of that numbered
|
574 |
+
version or of any later version published by the Free Software
|
575 |
+
Foundation. If the Program does not specify a version number of the
|
576 |
+
GNU General Public License, you may choose any version ever published
|
577 |
+
by the Free Software Foundation.
|
578 |
+
|
579 |
+
If the Program specifies that a proxy can decide which future
|
580 |
+
versions of the GNU General Public License can be used, that proxy's
|
581 |
+
public statement of acceptance of a version permanently authorizes you
|
582 |
+
to choose that version for the Program.
|
583 |
+
|
584 |
+
Later license versions may give you additional or different
|
585 |
+
permissions. However, no additional obligations are imposed on any
|
586 |
+
author or copyright holder as a result of your choosing to follow a
|
587 |
+
later version.
|
588 |
+
|
589 |
+
15. Disclaimer of Warranty.
|
590 |
+
|
591 |
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
592 |
+
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
593 |
+
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
594 |
+
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
595 |
+
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
596 |
+
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
597 |
+
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
598 |
+
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
599 |
+
|
600 |
+
16. Limitation of Liability.
|
601 |
+
|
602 |
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
603 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
604 |
+
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
605 |
+
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
606 |
+
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
607 |
+
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
608 |
+
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
609 |
+
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
610 |
+
SUCH DAMAGES.
|
611 |
+
|
612 |
+
17. Interpretation of Sections 15 and 16.
|
613 |
+
|
614 |
+
If the disclaimer of warranty and limitation of liability provided
|
615 |
+
above cannot be given local legal effect according to their terms,
|
616 |
+
reviewing courts shall apply local law that most closely approximates
|
617 |
+
an absolute waiver of all civil liability in connection with the
|
618 |
+
Program, unless a warranty or assumption of liability accompanies a
|
619 |
+
copy of the Program in return for a fee.
|
620 |
+
|
621 |
+
END OF TERMS AND CONDITIONS
|
622 |
+
|
623 |
+
How to Apply These Terms to Your New Programs
|
624 |
+
|
625 |
+
If you develop a new program, and you want it to be of the greatest
|
626 |
+
possible use to the public, the best way to achieve this is to make it
|
627 |
+
free software which everyone can redistribute and change under these terms.
|
628 |
+
|
629 |
+
To do so, attach the following notices to the program. It is safest
|
630 |
+
to attach them to the start of each source file to most effectively
|
631 |
+
state the exclusion of warranty; and each file should have at least
|
632 |
+
the "copyright" line and a pointer to where the full notice is found.
|
633 |
+
|
634 |
+
<one line to give the program's name and a brief idea of what it does.>
|
635 |
+
Copyright (C) <year> <name of author>
|
636 |
+
|
637 |
+
This program is free software: you can redistribute it and/or modify
|
638 |
+
it under the terms of the GNU General Public License as published by
|
639 |
+
the Free Software Foundation, either version 3 of the License, or
|
640 |
+
(at your option) any later version.
|
641 |
+
|
642 |
+
This program is distributed in the hope that it will be useful,
|
643 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
644 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
645 |
+
GNU General Public License for more details.
|
646 |
+
|
647 |
+
You should have received a copy of the GNU General Public License
|
648 |
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
649 |
+
|
650 |
+
Also add information on how to contact you by electronic and paper mail.
|
651 |
+
|
652 |
+
If the program does terminal interaction, make it output a short
|
653 |
+
notice like this when it starts in an interactive mode:
|
654 |
+
|
655 |
+
<program> Copyright (C) <year> <name of author>
|
656 |
+
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
657 |
+
This is free software, and you are welcome to redistribute it
|
658 |
+
under certain conditions; type `show c' for details.
|
659 |
+
|
660 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
661 |
+
parts of the General Public License. Of course, your program's commands
|
662 |
+
might be different; for a GUI interface, you would use an "about box".
|
663 |
+
|
664 |
+
You should also get your employer (if you work as a programmer) or school,
|
665 |
+
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
666 |
+
For more information on this, and how to apply and follow the GNU GPL, see
|
667 |
+
<https://www.gnu.org/licenses/>.
|
668 |
+
|
669 |
+
The GNU General Public License does not permit incorporating your program
|
670 |
+
into proprietary programs. If your program is a subroutine library, you
|
671 |
+
may consider it more useful to permit linking proprietary applications with
|
672 |
+
the library. If this is what you want to do, use the GNU Lesser General
|
673 |
+
Public License instead of this License. But first, please read
|
674 |
+
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
README.md
CHANGED
@@ -1,11 +1,67 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# GeospaCy
|
2 |
+
|
3 |
+
|
4 |
+
**GeospaCy** is a web application built in Python language used for extracting spatial relation entities (spatRE) from text and Geo-referenced them.
|
5 |
+
|
6 |
+
## Installation
|
7 |
+
There are few Python packages that are needed to install for running the application
|
8 |
+
|
9 |
+
1. Install spacy for natural language processing (NLP) tasks
|
10 |
+
```sh
|
11 |
+
pip install spacy
|
12 |
+
```
|
13 |
+
2. Install gensim library for data preprocessing
|
14 |
+
```sh
|
15 |
+
pip install gensim
|
16 |
+
```
|
17 |
+
3. Install streamit library for running web application
|
18 |
+
```sh
|
19 |
+
pip install streamlit
|
20 |
+
```
|
21 |
+
4. Install spacy-streamlit for display named entities (spatRE) in the text
|
22 |
+
```sh
|
23 |
+
pip install spacy-streamlit
|
24 |
+
```
|
25 |
+
|
26 |
+
5. Install GeoPandas
|
27 |
+
```sh
|
28 |
+
pip install geopandas
|
29 |
+
```
|
30 |
+
6. Install folium library for manipulating your data in Python, then visualize it in a Leaflet map via folium.
|
31 |
+
|
32 |
+
```sh
|
33 |
+
pip install folium
|
34 |
+
```
|
35 |
+
7. Install streamlit-folium library to visualize Leaflet map in streamlit web application
|
36 |
+
|
37 |
+
```sh
|
38 |
+
pip install streamlit-folium
|
39 |
+
```
|
40 |
+
|
41 |
+
## How to run the web application
|
42 |
+
|
43 |
+
```sh
|
44 |
+
streamlit run 1_🏠_Parser.py
|
45 |
+
```
|
46 |
+
|
47 |
+
## [Cite this work](https://github.com/mehtab-alam/GeospaCy/)
|
48 |
+
|
49 |
+
```latex
|
50 |
+
@inproceedings{mehtab-alam-etal-2024-geospacy,
|
51 |
+
title = "GeospaCy: A tool for extraction and geographical referencing of spatial expressions in textual data",
|
52 |
+
author = "Mehtab Alam, Syed and
|
53 |
+
Arsevska, Elena and
|
54 |
+
Roche, Mathieu and
|
55 |
+
Teisseire, Maguelonne",
|
56 |
+
editor = "Aletras, Nikolaos and
|
57 |
+
De Clercq, Orphee",
|
58 |
+
booktitle = "Proceedings of the 18th Conference of the European Chapter of the Association for Computational Linguistics: System Demonstrations",
|
59 |
+
month = mar,
|
60 |
+
year = "2024",
|
61 |
+
address = "St. Julians, Malta",
|
62 |
+
publisher = "Association for Computational Linguistics",
|
63 |
+
url = "https://aclanthology.org/2024.eacl-demo.13",
|
64 |
+
pages = "115--126",
|
65 |
+
}
|
66 |
+
```
|
67 |
+
|
__pycache__/geospacy.cpython-310.pyc
ADDED
Binary file (3.18 kB). View file
|
|
__pycache__/geospacy.cpython-39.pyc
ADDED
Binary file (2.43 kB). View file
|
|
__pycache__/llm_coding.cpython-310.pyc
ADDED
Binary file (151 Bytes). View file
|
|
__pycache__/llm_ent_extract.cpython-310.pyc
ADDED
Binary file (6.9 kB). View file
|
|
__pycache__/regex_spatial.cpython-310.pyc
ADDED
Binary file (2.75 kB). View file
|
|
__pycache__/regex_spatial.cpython-311.pyc
ADDED
Binary file (4.43 kB). View file
|
|
__pycache__/regex_spatial.cpython-38.pyc
ADDED
Binary file (2.84 kB). View file
|
|
__pycache__/regex_spatial.cpython-39.pyc
ADDED
Binary file (2.79 kB). View file
|
|
answer/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
answer/GPT4o.json
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"index": 1,
|
4 |
+
"instruction": "Plan a trip that involves determining the midpoint between Paris and London, and then finding another midpoint between this location and Paris to identify potential stopovers during travel.",
|
5 |
+
"steps": [
|
6 |
+
{"id": 1, "function": "Between", "inputs": ["Paris", "London"]},
|
7 |
+
{"id": 2, "function": "Between", "inputs": [1, "Paris"]}
|
8 |
+
]
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"index": 2,
|
12 |
+
"instruction": "Imagine you are planning a picnic hike in the Blue Mountains of Australia. Start your hike in Katoomba, move southeast for 3 kilometers, and then find a scenic midpoint between your new location and Echo Point to set up your picnic.",
|
13 |
+
"steps": [
|
14 |
+
{"id": 1, "function": "Relative", "inputs": ["Katoomba", "southeast", "3 km"]},
|
15 |
+
{"id": 2, "function": "Between", "inputs": [1, "Echo Point"]}
|
16 |
+
]
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"index": 3,
|
20 |
+
"instruction": "Plan a hiking route starting at Scafell Pike and travel 8 km to the west, then continue proceeding another 9 km westward.",
|
21 |
+
"steps": [
|
22 |
+
{"id": 1, "function": "Relative", "inputs": ["Scafell Pike", "west", "8 km"]},
|
23 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "9 km"]}
|
24 |
+
]
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"index": 4,
|
28 |
+
"instruction": "Starting from the Colosseum in Rome, navigate 8 kilometers at a 25° azimuth to go towards the northeast, and then move a further 2 kilometers in the northeast direction. Determine if this is a suitable location for a new tourist station setup.",
|
29 |
+
"steps": [
|
30 |
+
{"id": 1, "function": "Relative", "inputs": ["Colosseum", "northeast", "8 km"]},
|
31 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "2 km"]}
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"index": 5,
|
36 |
+
"instruction": "Set up a communications relay point 4 km in the direction of 36° from Jasper, Alberta and then find the midpoint between this point and Banff, Alberta.",
|
37 |
+
"steps": [
|
38 |
+
{"id": 1, "function": "Relative", "inputs": ["Jasper, Alberta", "36°", "4 km"]},
|
39 |
+
{"id": 2, "function": "Between", "inputs": [1, "Banff, Alberta"]}
|
40 |
+
]
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"index": 6,
|
44 |
+
"instruction": "Identify the midpoint between the Statue of Liberty and the Eiffel Tower. From this midpoint, proceed 8 kilometers due west to establish a new GPS tracking station.",
|
45 |
+
"steps": [
|
46 |
+
{"id": 1, "function": "Between", "inputs": ["Statue of Liberty", "Eiffel Tower"]},
|
47 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "8 km"]}
|
48 |
+
]
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"index": 7,
|
52 |
+
"instruction": "Determine a strategic location for a new lookout post by first finding the midpoint between New Orleans, USA, and Veracruz, Mexico. Then, identify a spot 8 km southwest of this midpoint.",
|
53 |
+
"steps": [
|
54 |
+
{"id": 1, "function": "Between", "inputs": ["New Orleans, USA", "Veracruz, Mexico"]},
|
55 |
+
{"id": 2, "function": "Relative", "inputs": [1, "southwest", "8 km"]}
|
56 |
+
]
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"index": 8,
|
60 |
+
"instruction": "Plan a marine survey starting at Santorini, Greece: First, move 9 km south to begin the survey in a new area. Then, identify the midpoint between Santorini and this new location, and move 1 km south from it for further exploration. From the original midpoint, proceed 5 km at an azimuth of 150° towards a final survey site. Find the midpoint between this location and the previous exploration point for setting a central sampling station.",
|
61 |
+
"steps": [
|
62 |
+
{"id": 1, "function": "Relative", "inputs": ["Santorini", "south", "9 km"]},
|
63 |
+
{"id": 2, "function": "Between", "inputs": ["Santorini", 1]},
|
64 |
+
{"id": 3, "function": "Relative", "inputs": [2, "south", "1 km"]},
|
65 |
+
{"id": 4, "function": "Relative", "inputs": [2, "southeast", "5 km"]},
|
66 |
+
{"id": 5, "function": "Between", "inputs": [3, 4]}
|
67 |
+
]
|
68 |
+
},
|
69 |
+
{
|
70 |
+
"index": 9,
|
71 |
+
"instruction": "Plan a central spot for a camping trip by first finding the midpoint between Mont Blanc and Matterhorn, then find the midpoint between this point and Chamonix to refine the camping location.",
|
72 |
+
"steps": [
|
73 |
+
{"id": 1, "function": "Between", "inputs": ["Mont Blanc", "Matterhorn"]},
|
74 |
+
{"id": 2, "function": "Between", "inputs": [1, "Chamonix"]}
|
75 |
+
]
|
76 |
+
},
|
77 |
+
{
|
78 |
+
"index": 10,
|
79 |
+
"instruction": "Begin your geocaching adventure at Central Park in New York City. Move southwest for 9 km. Then head east for another 7 km. Finally, go back for an additional 1 km to find the hidden cache location.",
|
80 |
+
"steps": [
|
81 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park", "southwest", "9 km"]},
|
82 |
+
{"id": 2, "function": "Relative", "inputs": [1, "east", "7 km"]},
|
83 |
+
{"id": 3, "function": "Relative", "inputs": [2, "west", "1 km"]}
|
84 |
+
]
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"index": 11,
|
88 |
+
"instruction": "Plan a meeting point by moving 3 kilometers east of Central Park and then find a midpoint between this new location and Central Park.",
|
89 |
+
"steps": [
|
90 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park", "east", "3 km"]},
|
91 |
+
{"id": 2, "function": "Between", "inputs": ["Central Park", 1]}
|
92 |
+
]
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"index": 12,
|
96 |
+
"instruction": "Identify the location that is 9 km to the southeast of Paris city center to set up a monitoring station.",
|
97 |
+
"steps": [
|
98 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris", "southeast", "9 km"]}
|
99 |
+
]
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"index": 13,
|
103 |
+
"instruction": "Design a network of emergency medical drone hubs across Luxembourg. Start at the city hospital in Esch-sur-Alzette. First, plan a drone station 4 km to the northeast to reach nearby suburbs. Then, from there, move 6 km at an azimuth angle of 45° to cover rural areas toward Bettembourg. Continue by traveling 3 km at an azimuth of 190° to extend reach into southern valleys. Finally, identify the midpoint between this last location and the starting hospital as a backup drone relay site.",
|
104 |
+
"steps": [
|
105 |
+
{"id": 1, "function": "Relative", "inputs": ["Esch-sur-Alzette", "northeast", "4 km"]},
|
106 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "6 km"]},
|
107 |
+
{"id": 3, "function": "Relative", "inputs": [2, "south-southwest", "3 km"]},
|
108 |
+
{"id": 4, "function": "Between", "inputs": ["Esch-sur-Alzette", 3]}
|
109 |
+
]
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"index": 14,
|
113 |
+
"instruction": "Plan a scenic hiking route starting from Banff, Alberta. First, travel northwest for 2 km to reach a noted viewpoint. From there, continue northeast for 4 km, potentially spotting wildlife along the way. Finally, identify a midpoint between Banff and your current location to set a resting spot or picnic area for optimal views and convenience.",
|
114 |
+
"steps": [
|
115 |
+
{"id": 1, "function": "Relative", "inputs": ["Banff", "northwest", "2 km"]},
|
116 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "4 km"]},
|
117 |
+
{"id": 3, "function": "Between", "inputs": ["Banff", 2]}
|
118 |
+
]
|
119 |
+
},
|
120 |
+
{
|
121 |
+
"index": 15,
|
122 |
+
"instruction": "Start at Central Park in New York City. Move northeast for 2 km to reach the area near The Met Cloisters in Fort Tryon Park. From there, head in the direction of 333° for 7 km towards the intersection of Riverside Drive and W 165th St. Finally, navigate 9 km in the direction of 62° to reach a suitable spot near Yonkers Avenue in Yonkers for the meteorological station setup.",
|
123 |
+
"steps": [
|
124 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park", "northeast", "2 km"]},
|
125 |
+
{"id": 2, "function": "Relative", "inputs": [1, "333°", "7 km"]},
|
126 |
+
{"id": 3, "function": "Relative", "inputs": [2, "62°", "9 km"]}
|
127 |
+
]
|
128 |
+
},
|
129 |
+
{
|
130 |
+
"index": 16,
|
131 |
+
"instruction": "Start at the Hellisheiði Geothermal Power Plant in Iceland and identify the area 5 kilometers to the northwest to assess potential expansion sites for sustainable energy infrastructure.",
|
132 |
+
"steps": [
|
133 |
+
{"id": 1, "function": "Relative", "inputs": ["Hellisheiði Geothermal Power Plant", "northwest", "5 km"]}
|
134 |
+
]
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"index": 17,
|
138 |
+
"instruction": "Plan a geological survey in the Cape Town area. First, find a point 3 km southwest of Signal Hill. Then, find the midpoint between this new location and Signal Hill. Next, calculate the midpoint between this result and Cape Town. Finally, determine the central point between all computed midpoints to establish a base camp for your survey operations.",
|
139 |
+
"steps": [
|
140 |
+
{"id": 1, "function": "Relative", "inputs": ["Signal Hill", "southwest", "3 km"]},
|
141 |
+
{"id": 2, "function": "Between", "inputs": [1, "Signal Hill"]},
|
142 |
+
{"id": 3, "function": "Between", "inputs": [2, "Cape Town"]},
|
143 |
+
{"id": 4, "function": "Between", "inputs": [2, 3]}
|
144 |
+
]
|
145 |
+
},
|
146 |
+
{
|
147 |
+
"index": 18,
|
148 |
+
"instruction": "Start at Praça do Comércio in Lisbon. First, calculate a point 1 km north from this location. Then, find the midpoint between this new location and Praça do Comércio. Finally, determine the midpoint between Praça do Comércio and the previously calculated midpoint to navigate effectively around the city.",
|
149 |
+
"steps": [
|
150 |
+
{"id": 1, "function": "Relative", "inputs": ["Praça do Comércio", "north", "1 km"]},
|
151 |
+
{"id": 2, "function": "Between", "inputs": ["Praça do Comércio", 1]},
|
152 |
+
{"id": 3, "function": "Between", "inputs": ["Praça do Comércio", 2]}
|
153 |
+
]
|
154 |
+
},
|
155 |
+
{
|
156 |
+
"index": 19,
|
157 |
+
"instruction": "Starting at the South Pole, travel 4 kilometers at an angle of 65° to find Point A. Determine the midpoint between the South Pole and Point A. From this midpoint, travel 7 kilometers at an angle of 184° to reach McMurdo Station.",
|
158 |
+
"steps": [
|
159 |
+
{"id": 1, "function": "Relative", "inputs": ["South Pole", "north-northeast", "4 km"]},
|
160 |
+
{"id": 2, "function": "Between", "inputs": ["South Pole", 1]},
|
161 |
+
{"id": 3, "function": "Relative", "inputs": [2, "slightly south of due south", "7 km"]}
|
162 |
+
]
|
163 |
+
},
|
164 |
+
{
|
165 |
+
"index": 20,
|
166 |
+
"instruction": "Identify a new exploration point 10 km northwest of the base camp at Yosemite National Park.",
|
167 |
+
"steps": [
|
168 |
+
{"id": 1, "function": "Relative", "inputs": ["Yosemite National Park", "northwest", "10 km"]}
|
169 |
+
]
|
170 |
+
}
|
171 |
+
]
|
call_llm.py
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from openai import OpenAI
|
2 |
+
import re
|
3 |
+
|
4 |
+
client = OpenAI(
|
5 |
+
api_key='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'
|
6 |
+
)
|
7 |
+
system_prompt = prompt = f"""You are an expert in interpreting directional descriptions and converting them into precise bearing angles.
|
8 |
+
|
9 |
+
**Rules:**
|
10 |
+
- The reference direction is **North (0°)**.
|
11 |
+
- **East is 90°**, **South is 180°**, and **West is 270°**.
|
12 |
+
- Intermediate directions follow standard bearing notation:
|
13 |
+
- "Northeast" → 45°
|
14 |
+
- "Southeast" → 135°
|
15 |
+
- "Southwest" → 225°
|
16 |
+
- "Northwest" → 315°
|
17 |
+
- Some relative directions follow specific rules:
|
18 |
+
- "South 30 degrees east." → 150°
|
19 |
+
- "60 degrees west of north." → 300°
|
20 |
+
- "North 30 degrees east." → 30°
|
21 |
+
- "20 degrees east of west." → 160°
|
22 |
+
|
23 |
+
- "Direction1 of Direction2" (e.g., "north of east"):
|
24 |
+
the direction from Direction 2 to Direction 1. For example, 30 degrees north of west means turning from the west, which is 270 degrees, to the north, which is 360 (0) degrees. So 270 + 20 = 290 degrees.
|
25 |
+
- "Direction1 X degrees Direction2" (e.g., "North 30 degrees east"):
|
26 |
+
This phrase reverses the focus: the primary reference is Direction1, and the deviation is toward Direction2. For instance, "North 30 degrees east" means you start facing north (0°) and turn eastward by 30 degrees. The direction angle is calculated by adding the deviation directly to the reference angle. In this case, starting at north (0°) and turning 30 degrees east results in a direction angle of 30 degrees (0° + 30° = 30°) measured clockwise from true north. Here, Direction1 is the anchor, and Direction2 defines the turn. Both phrases clarify orientation but prioritize different reference points.
|
27 |
+
|
28 |
+
At the end of your response, clearly indicate the final angle using the format:
|
29 |
+
`###X###`
|
30 |
+
|
31 |
+
|
32 |
+
|
33 |
+
Here is an example:
|
34 |
+
Input: 'Location A is 10 degrees west of south.'
|
35 |
+
Output: 'To determine the angle for the direction "10 degrees west of south," we need to:
|
36 |
+
1. Identify the starting reference direction which is South (180°).
|
37 |
+
2. Calculate the angle moving 10 degrees towards the west from the South direction.
|
38 |
+
|
39 |
+
Starting from South (180°), moving 10 degrees towards the west:
|
40 |
+
180° + 10° = 190°
|
41 |
+
|
42 |
+
Therefore, "Location A is 10 degrees west of south." is equivalent to **190°**
|
43 |
+
|
44 |
+
The final angle is: ###190°###'
|
45 |
+
|
46 |
+
Now, analyze the following text, determine the correct angle, and **provide step-by-step reasoning before outputting the final result**.
|
47 |
+
"""
|
48 |
+
# model = "gpt-3.5-turbo"
|
49 |
+
model = "gpt-4o"
|
50 |
+
|
51 |
+
def extract_number(text: str) -> float:
|
52 |
+
match = re.search(r"###(.*?)###", text)
|
53 |
+
if match:
|
54 |
+
num_str = match.group(1).strip()
|
55 |
+
num_str = re.sub(r'[^0-9.-]', '', num_str) # 移除非数字字符(保留数字、负号、小数点)
|
56 |
+
try:
|
57 |
+
return float(num_str) if '.' in num_str else int(num_str)
|
58 |
+
except ValueError:
|
59 |
+
pass
|
60 |
+
return None # 如果没有匹配到数字,则返回None
|
61 |
+
|
62 |
+
def gpt4o(system_prompt, text):
|
63 |
+
|
64 |
+
math_bot_messages = [
|
65 |
+
{"role": "system",
|
66 |
+
"content": system_prompt},
|
67 |
+
{"role": "user", "content": text},
|
68 |
+
]
|
69 |
+
chat_completion = client.chat.completions.create(
|
70 |
+
messages=math_bot_messages,
|
71 |
+
model=model,
|
72 |
+
)
|
73 |
+
|
74 |
+
result = chat_completion.choices[0].message.content
|
75 |
+
print(result)
|
76 |
+
return extract_number(result)
|
77 |
+
|
78 |
+
# print(gpt4o(system_prompt, "Location A is 10 degrees south of west."))
|
79 |
+
# print(gpt4o(system_prompt, "Location A is 20 degrees north of west."))
|
80 |
+
|
dataset/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
dataset/dataset_10.json
ADDED
@@ -0,0 +1,166 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"index": 1,
|
4 |
+
"instruction": "",
|
5 |
+
"steps": [
|
6 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "southwest", "7 km"]}
|
7 |
+
]
|
8 |
+
},
|
9 |
+
{
|
10 |
+
"index": 2,
|
11 |
+
"instruction": "",
|
12 |
+
"steps": [
|
13 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "southwest", "6 km"]}
|
14 |
+
]
|
15 |
+
},
|
16 |
+
{
|
17 |
+
"index": 3,
|
18 |
+
"instruction": "",
|
19 |
+
"steps": [
|
20 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "west", "1 km"]},
|
21 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "5 km"]},
|
22 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "226°", "2 km"]}
|
23 |
+
]
|
24 |
+
},
|
25 |
+
{
|
26 |
+
"index": 4,
|
27 |
+
"instruction": "",
|
28 |
+
"steps": [
|
29 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "south", "5 km"]}
|
30 |
+
]
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"index": 5,
|
34 |
+
"instruction": "",
|
35 |
+
"steps": [
|
36 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "southwest", "4 km"]},
|
37 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_2", 1]},
|
38 |
+
{"id": 3, "function": "Between", "inputs": [2, "LOC_2"]}
|
39 |
+
]
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"index": 6,
|
43 |
+
"instruction": "",
|
44 |
+
"steps": [
|
45 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "southeast", "6 km"]}
|
46 |
+
]
|
47 |
+
},
|
48 |
+
{
|
49 |
+
"index": 7,
|
50 |
+
"instruction": "",
|
51 |
+
"steps": [
|
52 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "west", "4 km"]},
|
53 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_1", 1]},
|
54 |
+
{"id": 3, "function": "Between", "inputs": ["LOC_1", 2]}
|
55 |
+
]
|
56 |
+
},
|
57 |
+
{
|
58 |
+
"index": 8,
|
59 |
+
"instruction": "",
|
60 |
+
"steps": [
|
61 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "171°", "7 km"]}
|
62 |
+
]
|
63 |
+
},
|
64 |
+
{
|
65 |
+
"index": 9,
|
66 |
+
"instruction": "",
|
67 |
+
"steps": [
|
68 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "240°", "9 km"]},
|
69 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "6 km"]},
|
70 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "237°", "2 km"]}
|
71 |
+
]
|
72 |
+
},
|
73 |
+
{
|
74 |
+
"index": 10,
|
75 |
+
"instruction": "",
|
76 |
+
"steps": [
|
77 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "northwest", "7 km"]},
|
78 |
+
{"id": 2, "function": "Relative", "inputs": [1, "southwest", "7 km"]},
|
79 |
+
{"id": 3, "function": "Between", "inputs": ["LOC_1", 2]}
|
80 |
+
]
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"index": 11,
|
84 |
+
"instruction": "",
|
85 |
+
"steps": [
|
86 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "245°", "5 km"]},
|
87 |
+
{"id": 2, "function": "Relative", "inputs": ["LOC_1", "north", "1 km"]},
|
88 |
+
{"id": 3, "function": "Between", "inputs": [2, 1]},
|
89 |
+
{"id": 4, "function": "Between", "inputs": [3, 2]}
|
90 |
+
]
|
91 |
+
},
|
92 |
+
{
|
93 |
+
"index": 12,
|
94 |
+
"instruction": "",
|
95 |
+
"steps": [
|
96 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "327°", "10 km"]},
|
97 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "239°", "7 km"]},
|
98 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
99 |
+
]
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"index": 13,
|
103 |
+
"instruction": "",
|
104 |
+
"steps": [
|
105 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "154°", "6 km"]},
|
106 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "163°", "3 km"]}
|
107 |
+
]
|
108 |
+
},
|
109 |
+
{
|
110 |
+
"index": 14,
|
111 |
+
"instruction": "",
|
112 |
+
"steps": [
|
113 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "north", "8 km"]},
|
114 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_1"]}
|
115 |
+
]
|
116 |
+
},
|
117 |
+
{
|
118 |
+
"index": 15,
|
119 |
+
"instruction": "",
|
120 |
+
"steps": [
|
121 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "northwest", "4 km"]},
|
122 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_1", 1]}
|
123 |
+
]
|
124 |
+
},
|
125 |
+
{
|
126 |
+
"index": 16,
|
127 |
+
"instruction": "",
|
128 |
+
"steps": [
|
129 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "268°", "7 km"]},
|
130 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_1"]}
|
131 |
+
]
|
132 |
+
},
|
133 |
+
{
|
134 |
+
"index": 17,
|
135 |
+
"instruction": "",
|
136 |
+
"steps": [
|
137 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "70°", "9 km"]},
|
138 |
+
{"id": 2, "function": "Relative", "inputs": [1, "southeast", "4 km"]}
|
139 |
+
]
|
140 |
+
},
|
141 |
+
{
|
142 |
+
"index": 18,
|
143 |
+
"instruction": "",
|
144 |
+
"steps": [
|
145 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "north", "3 km"]},
|
146 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "21°", "8 km"]}
|
147 |
+
]
|
148 |
+
},
|
149 |
+
{
|
150 |
+
"index": 19,
|
151 |
+
"instruction": "",
|
152 |
+
"steps": [
|
153 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "199°", "8 km"]},
|
154 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "270°", "8 km"]},
|
155 |
+
{"id": 3, "function": "Between", "inputs": ["LOC_1", 2]}
|
156 |
+
]
|
157 |
+
},
|
158 |
+
{
|
159 |
+
"index": 20,
|
160 |
+
"instruction": "",
|
161 |
+
"steps": [
|
162 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "south", "1 km"]},
|
163 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_1", 1]}
|
164 |
+
]
|
165 |
+
}
|
166 |
+
]
|
dataset/dataset_100.json
ADDED
@@ -0,0 +1,1005 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"index": 1,
|
4 |
+
"instruction": "Plan a trip that involves determining the midpoint between Paris and London, and then finding another midpoint between this location and Paris to identify potential stopovers during travel.",
|
5 |
+
"steps": [
|
6 |
+
{"id": 1, "function": "Between", "inputs": ["Paris, France", "London, England"]},
|
7 |
+
{"id": 2, "function": "Between", "inputs": [1, "Paris, France"]}
|
8 |
+
]
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"index": 2,
|
12 |
+
"instruction": "Imagine you are planning a picnic hike in the Blue Mountains of Australia. Start your hike in Katoomba, move southeast for 3 kilometers, and then find a scenic midpoint between your new location and Echo Point to set up your picnic.",
|
13 |
+
"steps": [
|
14 |
+
{"id": 1, "function": "Relative", "inputs": ["Katoomba", "southeast", "3 km"]},
|
15 |
+
{"id": 2, "function": "Between", "inputs": [1, "Echo Point"]}
|
16 |
+
]
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"index": 3,
|
20 |
+
"instruction": "Plan a hiking route starting at Scafell Pike and travel 8 km to the west, then continue proceeding another 9 km westward.",
|
21 |
+
"steps": [
|
22 |
+
{"id": 1, "function": "Relative", "inputs": ["Scafell Pike", "west", "8 km"]},
|
23 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "9 km"]}
|
24 |
+
]
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"index": 4,
|
28 |
+
"instruction": "Starting from the Colosseum in Rome, navigate 8 kilometers at a 25° azimuth to go towards the northeast, and then move a further 2 kilometers in the northeast direction. Determine if this is a suitable location for a new tourist station setup.",
|
29 |
+
"steps": [
|
30 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Colosseum, Rome", "25°", "8 km"]},
|
31 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "2 km"]}
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"index": 5,
|
36 |
+
"instruction": "Set up a communications relay point 4 km in the direction of 36° from Jasper, Alberta and then find the midpoint between this point and Banff, Alberta.",
|
37 |
+
"steps": [
|
38 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Jasper, Alberta", "36°", "4 km"]},
|
39 |
+
{"id": 2, "function": "Between", "inputs": ["Banff, Alberta", 1]}
|
40 |
+
]
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"index": 6,
|
44 |
+
"instruction": "Identify the midpoint between the Statue of Liberty and the Eiffel Tower. From this midpoint, proceed 8 kilometers due west to establish a new GPS tracking station.",
|
45 |
+
"steps": [
|
46 |
+
{"id": 1, "function": "Between", "inputs": ["Eiffel Tower", "Statue of Liberty"]},
|
47 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "266°", "8 km"]}
|
48 |
+
]
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"index": 7,
|
52 |
+
"instruction": "Determine a strategic location for a new lookout post by first finding the midpoint between New Orleans, USA, and Veracruz, Mexico. Then, identify a spot 8 km southwest of this midpoint.",
|
53 |
+
"steps": [
|
54 |
+
{"id": 1, "function": "Between", "inputs": ["New Orleans, USA", "Veracruz, Mexico"]},
|
55 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "220°", "8 km"]}
|
56 |
+
]
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"index": 8,
|
60 |
+
"instruction": "Plan a marine survey starting at Santorini, Greece: First, move 9 km south to begin the survey in a new area. Then, identify the midpoint between Santorini and this new location, and move 1 km south from it for further exploration. From the original midpoint, proceed 5 km at an azimuth of 150° towards a final survey site. Find the midpoint between this location and the previous exploration point for setting a central sampling station.",
|
61 |
+
"steps": [
|
62 |
+
{"id": 1, "function": "Relative", "inputs": ["Santorini, Greece", "south", "9 km"]},
|
63 |
+
{"id": 2, "function": "Between", "inputs": ["Santorini, Greece", 1]},
|
64 |
+
{"id": 3, "function": "Relative", "inputs": [1, "south", "1 km"]},
|
65 |
+
{"id": 4, "function": "Azimuth", "inputs": [2, "150°", "5 km"]},
|
66 |
+
{"id": 5, "function": "Between", "inputs": [3, 4]}
|
67 |
+
]
|
68 |
+
},
|
69 |
+
{
|
70 |
+
"index": 9,
|
71 |
+
"instruction": "Plan a central spot for a camping trip by first finding the midpoint between Mont Blanc and Matterhorn, then find the midpoint between this point and Chamonix to refine the camping location.",
|
72 |
+
"steps": [
|
73 |
+
{"id": 1, "function": "Between", "inputs": ["Mont Blanc, France-Italy border", "Matterhorn, Switzerland-Italy border"]},
|
74 |
+
{"id": 2, "function": "Between", "inputs": [1, "Chamonix, France"]}
|
75 |
+
]
|
76 |
+
},
|
77 |
+
{
|
78 |
+
"index": 10,
|
79 |
+
"instruction": "Begin your geocaching adventure at Central Park in New York City. Move southwest for 9 km. Then head east for another 7 km. Finally, go west for an additional 1 km to find the hidden cache location.",
|
80 |
+
"steps": [
|
81 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Central Park, New York City", "215°", "9 km"]},
|
82 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "99°", "7 km"]},
|
83 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "285°", "1 km"]}
|
84 |
+
]
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"index": 11,
|
88 |
+
"instruction": "Plan a meeting point by moving 3 kilometers east of Central Park and then find a midpoint between this new location and Central Park.",
|
89 |
+
"steps": [
|
90 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, Manhattan, New York", "east", "3 km"]},
|
91 |
+
{"id": 2, "function": "Between", "inputs": [1, "Central Park, Manhattan, New York"]}
|
92 |
+
]
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"index": 12,
|
96 |
+
"instruction": "Identify the location that is 9 km to the southeast of Paris city center to set up a monitoring station.",
|
97 |
+
"steps": [
|
98 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris", "southeast", "9 km"]}
|
99 |
+
]
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"index": 13,
|
103 |
+
"instruction": "Set up a series of geocaching locations in Central Park, starting at the Central Park Carousel. First, place the first geocache 6 km north. Next, move 5 km at an angle of 3° to place the second cache. Then, go 3 km at 199° from the second cache for the third one. Finally, find the midpoint between this third cache location and the Carousel for a bonus cache.",
|
104 |
+
"steps": [
|
105 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park Carousel, New York", "north", "6 km"]},
|
106 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "3°", "5 km"]},
|
107 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "199°", "3 km"]},
|
108 |
+
{"id": 4, "function": "Between", "inputs": [3, "Central Park Carousel, New York"]}
|
109 |
+
]
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"index": 14,
|
113 |
+
"instruction": "Plan a scenic hiking route starting from Banff, Alberta. First, travel northwest for 2 km to reach a noted viewpoint. From there, continue northeast for 4 km, potentially spotting wildlife along the way. Finally, identify a midpoint between Banff and your current location to set a resting spot or picnic area for optimal views and convenience.",
|
114 |
+
"steps": [
|
115 |
+
{"id": 1, "function": "Relative", "inputs": ["Banff", "northwest", "2 km"]},
|
116 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "4 km"]},
|
117 |
+
{"id": 3, "function": "Between", "inputs": ["Banff", 2]}
|
118 |
+
]
|
119 |
+
},
|
120 |
+
{
|
121 |
+
"index": 15,
|
122 |
+
"instruction": "Start at Central Park in New York City. Move northeast for 2 km to reach the area near The Met Cloisters in Fort Tryon Park. From there, head in the direction of 333° for 7 km towards the intersection of Riverside Drive and W 165th St. Finally, navigate 9 km in the direction of 62° to reach a suitable spot near Yonkers Avenue in Yonkers for the meteorological station setup.",
|
123 |
+
"steps": [
|
124 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park", "northeast", "2 km"]},
|
125 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "333°", "7 km"]},
|
126 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "62°", "9 km"]}
|
127 |
+
]
|
128 |
+
},
|
129 |
+
{
|
130 |
+
"index": 16,
|
131 |
+
"instruction": "Begin at Central Park in New York City and determine the area situated 5 kilometers to the east for the next phase of environmental monitoring.",
|
132 |
+
"steps": [
|
133 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, New York City", "east", "5 km"]}
|
134 |
+
]
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"index": 17,
|
138 |
+
"instruction": "Plan a geological survey in the Cape Town area. First, find a point 3 km southwest of Signal Hill. Then, find the midpoint between this new location and Signal Hill. Next, calculate the midpoint between this result and Cape Town. Finally, determine the central point between all computed midpoints to establish a base camp for your survey operations.",
|
139 |
+
"steps": [
|
140 |
+
{"id": 1, "function": "Relative", "inputs": ["Signal Hill", "southwest", "3 km"]},
|
141 |
+
{"id": 2, "function": "Between", "inputs": [1, "Signal Hill"]},
|
142 |
+
{"id": 3, "function": "Between", "inputs": ["Cape Town", 1]},
|
143 |
+
{"id": 4, "function": "Between", "inputs": [2, 3]}
|
144 |
+
]
|
145 |
+
},
|
146 |
+
{
|
147 |
+
"index": 18,
|
148 |
+
"instruction": "Start at Praça do Comércio in Lisbon. First, calculate a point 1 km north from this location. Then, find the midpoint between this new location and Praça do Comércio. Finally, determine the midpoint between Praça do Comércio and the previously calculated midpoint to navigate effectively around the city.",
|
149 |
+
"steps": [
|
150 |
+
{"id": 1, "function": "Relative", "inputs": ["Praça do Comércio, Lisbon", "north", "1 km"]},
|
151 |
+
{"id": 2, "function": "Between", "inputs": [1, "Praça do Comércio, Lisbon"]},
|
152 |
+
{"id": 3, "function": "Between", "inputs": ["Praça do Comércio, Lisbon", 2]}
|
153 |
+
]
|
154 |
+
},
|
155 |
+
{
|
156 |
+
"index": 19,
|
157 |
+
"instruction": "Starting at the South Pole, travel 4 kilometers at an angle of 65° to find Point A. Determine the midpoint between the South Pole and Point A. From this midpoint, travel 7 kilometers at an angle of 184° to reach McMurdo Station.",
|
158 |
+
"steps": [
|
159 |
+
{"id": 1, "function": "Azimuth", "inputs": ["South Pole", "65°", "4 km"]},
|
160 |
+
{"id": 2, "function": "Between", "inputs": ["South Pole", 1]},
|
161 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "184°", "7 km"]}
|
162 |
+
]
|
163 |
+
},
|
164 |
+
{
|
165 |
+
"index": 20,
|
166 |
+
"instruction": "Identify a new exploration point 10 km northwest of the base camp at Yosemite National Park.",
|
167 |
+
"steps": [
|
168 |
+
{"id": 1, "function": "Relative", "inputs": ["Yosemite National Park", "northwest", "10 km"]}
|
169 |
+
]
|
170 |
+
},
|
171 |
+
{
|
172 |
+
"index": 1,
|
173 |
+
"instruction": "Identify potential locations for setting up weather stations in the area surrounding the Sydney Opera House. First, locate a point 10 km away in a direction of 166° from the Opera House. Then, find the midpoint between this point and the Opera House. Finally, calculate the midpoint between the Opera House and the previously determined midpoint to identify two strategic locations.",
|
174 |
+
"steps": [
|
175 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "166°", "10 km"]},
|
176 |
+
{"id": 2, "function": "Between", "inputs": [1, "Sydney Opera House"]},
|
177 |
+
{"id": 3, "function": "Between", "inputs": ["Sydney Opera House", 2]}
|
178 |
+
]
|
179 |
+
},
|
180 |
+
{
|
181 |
+
"index": 2,
|
182 |
+
"instruction": "Starting in Paris, France, identify a location 4 km to the east. Then, proceed an additional 9 km further east to determine the final point for another weather monitoring station.",
|
183 |
+
"steps": [
|
184 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Paris, France", "90°", "4 km"]},
|
185 |
+
{"id": 2, "function": "Relative", "inputs": [1, "east", "9 km"]}
|
186 |
+
]
|
187 |
+
},
|
188 |
+
{
|
189 |
+
"index": 3,
|
190 |
+
"instruction": "Determine a location for a scenic observation point by first moving 8 km south of Florence, Italy. Then, find the midpoint between this new location and the city center of Florence.",
|
191 |
+
"steps": [
|
192 |
+
{"id": 1, "function": "Relative", "inputs": ["Florence, Italy", "south", "8 km"]},
|
193 |
+
{"id": 2, "function": "Between", "inputs": [1, "Florence, Italy"]}
|
194 |
+
]
|
195 |
+
},
|
196 |
+
{
|
197 |
+
"index": 4,
|
198 |
+
"instruction": "You are at the New York Botanical Garden and wish to find a point 6 kilometers to the northwest and then determine the midpoint between this new position and the Botanical Garden. First, calculate the location 6 kilometers to the northwest, then find the midpoint between these two points.",
|
199 |
+
"steps": [
|
200 |
+
{"id": 1, "function": "Azimuth", "inputs": ["New York Botanical Garden", "339°", "6 km"]},
|
201 |
+
{"id": 2, "function": "Between", "inputs": [1, "New York Botanical Garden"]}
|
202 |
+
]
|
203 |
+
},
|
204 |
+
{
|
205 |
+
"index": 5,
|
206 |
+
"instruction": "Determine the optimal midpoint location starting from Central Park, New York, moving first 3 km northeast, then 3 km north from that point; also consider another point 3 km northeast from Central Park as your reference for calculation.",
|
207 |
+
"steps": [
|
208 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, New York", "northeast", "3 km"]},
|
209 |
+
{"id": 2, "function": "Relative", "inputs": [1, "north", "3 km"]},
|
210 |
+
{"id": 3, "function": "Relative", "inputs": ["Central Park, New York", "northeast", "3 km"]},
|
211 |
+
{"id": 4, "function": "Between", "inputs": [3, 2]}
|
212 |
+
]
|
213 |
+
},
|
214 |
+
{
|
215 |
+
"index": 6,
|
216 |
+
"instruction": "Find a spot for an additional activity northwest of Central Park, New York, within a 5 km radius for an outdoor event.",
|
217 |
+
"steps": [
|
218 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, New York", "northwest", "5 km"]}
|
219 |
+
]
|
220 |
+
},
|
221 |
+
{
|
222 |
+
"index": 7,
|
223 |
+
"instruction": "From the Eiffel Tower in Paris, navigate in the direction of 247° for 2 km to find a suitable location for the outdoor art installation.",
|
224 |
+
"steps": [
|
225 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Eiffel Tower, Paris", "247°", "2 km"]}
|
226 |
+
]
|
227 |
+
},
|
228 |
+
{
|
229 |
+
"index": 8,
|
230 |
+
"instruction": "Plan a scenic route starting from Milan. First, head southeast for 6 km to reach near Monza. Then, find the midpoint between this location and Milan. Finally, continue southeast from the midpoint for another 7 km to explore the charming countryside before heading back to your main route to Lake Como.",
|
231 |
+
"steps": [
|
232 |
+
{"id": 1, "function": "Relative", "inputs": ["Milan", "southeast", "6 km"]},
|
233 |
+
{"id": 2, "function": "Between", "inputs": [1, "Milan"]},
|
234 |
+
{"id": 3, "function": "Relative", "inputs": [2, "southeast", "7 km"]}
|
235 |
+
]
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"index": 9,
|
239 |
+
"instruction": "Start at Leura in Australia and determine an observation point by first moving 10 km northwest at 317° to find a new location. From this new location, proceed 3 km west at 255° to find another spot. Finally, calculate the midpoint between these two offset locations to establish your central observation point.",
|
240 |
+
"steps": [
|
241 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Leura, Australia", "317°", "10 km"]},
|
242 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "255°", "3 km"]},
|
243 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
244 |
+
]
|
245 |
+
},
|
246 |
+
{
|
247 |
+
"index": 10,
|
248 |
+
"instruction": "Start at the Eiffel Tower and walk 1 km west to explore the Trocadéro area. Then, head 6 km east to visit the iconic Louvre Museum.",
|
249 |
+
"steps": [
|
250 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower", "west", "1 km"]},
|
251 |
+
{"id": 2, "function": "Relative", "inputs": [1, "east", "6 km"]}
|
252 |
+
]
|
253 |
+
},
|
254 |
+
{
|
255 |
+
"index": 11,
|
256 |
+
"instruction": "Determine a suitable location for setting up a temporary medical camp near Nairobi, Kenya. Start by moving 5 km southeast from Nairobi and then find the midpoint between Nairobi and the newly identified location.",
|
257 |
+
"steps": [
|
258 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Nairobi, Kenya", "101°", "5 km"]},
|
259 |
+
{"id": 2, "function": "Between", "inputs": ["Nairobi, Kenya", 1]}
|
260 |
+
]
|
261 |
+
},
|
262 |
+
{
|
263 |
+
"index": 12,
|
264 |
+
"instruction": "Determine the location 4 km at a 34° azimuth from Berlin, Germany, for setting up a temporary weather monitoring station.",
|
265 |
+
"steps": [
|
266 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Berlin, Germany", "34°", "4 km"]}
|
267 |
+
]
|
268 |
+
},
|
269 |
+
{
|
270 |
+
"index": 13,
|
271 |
+
"instruction": "To establish a central hub for activities, start at Zuma Beach in Malibu. Proceed 4 kilometers southwest, roughly parallel to the coast. Then, determine the midpoint between this new location and Zuma Beach to set up your campsite.",
|
272 |
+
"steps": [
|
273 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Zuma Beach, Malibu", "261°", "4 km"]},
|
274 |
+
{"id": 2, "function": "Between", "inputs": ["Zuma Beach, Malibu", 1]}
|
275 |
+
]
|
276 |
+
},
|
277 |
+
{
|
278 |
+
"index": 14,
|
279 |
+
"instruction": "You are tasked with planning a reconnaissance mission starting from Banff, Alberta. First, move 7 km west from Banff to reach a new location. Determine the midpoint between this location and Banff. From this midpoint, proceed 8 km south to reach your final survey point.",
|
280 |
+
"steps": [
|
281 |
+
{"id": 1, "function": "Relative", "inputs": ["Banff, Alberta", "west", "7 km"]},
|
282 |
+
{"id": 2, "function": "Between", "inputs": [1, "Banff, Alberta"]},
|
283 |
+
{"id": 3, "function": "Relative", "inputs": [2, "south", "8 km"]}
|
284 |
+
]
|
285 |
+
},
|
286 |
+
{
|
287 |
+
"index": 15,
|
288 |
+
"instruction": "Plan a hiking route starting from Mount Tamalpais. First, navigate 5 kilometers southeast, then head 10 kilometers west, followed by an additional 4 kilometers west, to explore the surrounding wilderness area.",
|
289 |
+
"steps": [
|
290 |
+
{"id": 1, "function": "Relative", "inputs": ["Mount Tamalpais", "southeast", "5 km"]},
|
291 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "10 km"]},
|
292 |
+
{"id": 3, "function": "Relative", "inputs": [2, "west", "4 km"]}
|
293 |
+
]
|
294 |
+
},
|
295 |
+
{
|
296 |
+
"index": 16,
|
297 |
+
"instruction": "Start by finding a point 10 km west of the Eiffel Tower. Then, determine the midpoint between this location and the Eiffel Tower. Finally, find a location 1 km southwest of this midpoint.",
|
298 |
+
"steps": [
|
299 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower", "west", "10 km"]},
|
300 |
+
{"id": 2, "function": "Between", "inputs": ["Eiffel Tower", 1]},
|
301 |
+
{"id": 3, "function": "Relative", "inputs": [2, "southwest", "1 km"]}
|
302 |
+
]
|
303 |
+
},
|
304 |
+
{
|
305 |
+
"index": 17,
|
306 |
+
"instruction": "Plan the setup of a telecommunications relay network starting from New York City by calculating optimal intermediate points for relay placement. First, determine a position by moving 7 km north from New York City. Then, compute another point by moving 8 km at a 125° angle from New York City. Next, proceed 1 km northwest from your first calculated location. Once these locations are established, find the midpoint between your northwest adjustment and New York City. Finally, identify the midpoint between the position on the 125° azimuth and the previous midpoint to determine the best relay placement.",
|
307 |
+
"steps": [
|
308 |
+
{"id": 1, "function": "Relative", "inputs": ["New York City, USA", "north", "7 km"]},
|
309 |
+
{"id": 2, "function": "Azimuth", "inputs": ["New York City, USA", "125°", "8 km"]},
|
310 |
+
{"id": 3, "function": "Relative", "inputs": [1, "northwest", "1 km"]},
|
311 |
+
{"id": 4, "function": "Between", "inputs": [3, "New York City, USA"]},
|
312 |
+
{"id": 5, "function": "Between", "inputs": [2, 4]}
|
313 |
+
]
|
314 |
+
},
|
315 |
+
{
|
316 |
+
"index": 18,
|
317 |
+
"instruction": "You are in Paris, France. Move 2 kilometers northwest from the center of Paris to reach a new area of the city.",
|
318 |
+
"steps": [
|
319 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris, France", "northwest", "2 km"]}
|
320 |
+
]
|
321 |
+
},
|
322 |
+
{
|
323 |
+
"index": 19,
|
324 |
+
"instruction": "Determine the location 6 km west-southwest from the Sydney Opera House using an azimuth of 247°.",
|
325 |
+
"steps": [
|
326 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "247°", "6 km"]}
|
327 |
+
]
|
328 |
+
},
|
329 |
+
{
|
330 |
+
"index": 20,
|
331 |
+
"instruction": "Plan a rest stop for hikers 2 km northwest of Yosemite Village and find the point midway back between this location and the original starting point.",
|
332 |
+
"steps": [
|
333 |
+
{"id": 1, "function": "Relative", "inputs": ["Yosemite Village", "northwest", "2 km"]},
|
334 |
+
{"id": 2, "function": "Between", "inputs": [1, "Yosemite Village"]}
|
335 |
+
]
|
336 |
+
},
|
337 |
+
{
|
338 |
+
"index": 21,
|
339 |
+
"instruction": "Plan an expedition by establishing a research station in the Amazon rainforest. Start from Santarém, Brazil, then navigate as follows: travel southeast for 10 km; from there, go north for another 10 km; proceed in a 30° direction for 5 km, and finally, calculate the midpoint between the last two positions to determine the best spot for setting up the station.",
|
340 |
+
"steps": [
|
341 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Santarém, Brazil", "121°", "10 km"]},
|
342 |
+
{"id": 2, "function": "Relative", "inputs": [1, "north", "10 km"]},
|
343 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "30°", "5 km"]},
|
344 |
+
{"id": 4, "function": "Between", "inputs": [3, 2]}
|
345 |
+
]
|
346 |
+
},
|
347 |
+
{
|
348 |
+
"index": 22,
|
349 |
+
"instruction": "Plan a road trip from Los Angeles to San Francisco. First, determine a good stopping point by finding the midpoint of the journey, then plan an additional small voyage split between Los Angeles and this midpoint.",
|
350 |
+
"steps": [
|
351 |
+
{"id": 1, "function": "Between", "inputs": ["Los Angeles", "San Francisco"]},
|
352 |
+
{"id": 2, "function": "Between", "inputs": ["Los Angeles", 1]}
|
353 |
+
]
|
354 |
+
},
|
355 |
+
{
|
356 |
+
"index": 23,
|
357 |
+
"instruction": "Start from the Eiffel Tower in Paris, travel 1 km due north, and then find the midpoint between your original location at the Eiffel Tower and your new location to select a spot for a picnic.",
|
358 |
+
"steps": [
|
359 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Eiffel Tower, Paris", "346°", "1 km"]},
|
360 |
+
{"id": 2, "function": "Between", "inputs": ["Eiffel Tower, Paris", 1]}
|
361 |
+
]
|
362 |
+
},
|
363 |
+
{
|
364 |
+
"index": 24,
|
365 |
+
"instruction": "Plan a hiking trip between Zermatt, Switzerland, and Chamonix, France. Start by determining a new location 9 km away at 140° from Zermatt and another one 5 km away at 338° from Chamonix. Find the midpoint between these two new locations to identify a first potential meeting point. Further, calculate between this first meeting point and the new location from Chamonix for a secondary checkpoint. Finally, determine the last potential rest spot by finding the midpoint between the two new results obtained.",
|
366 |
+
"steps": [
|
367 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Zermatt, Switzerland", "140°", "9 km"]},
|
368 |
+
{"id": 2, "function": "Azimuth", "inputs": ["Chamonix, France", "338°", "5 km"]},
|
369 |
+
{"id": 3, "function": "Between", "inputs": [1, "Chamonix, France"]},
|
370 |
+
{"id": 4, "function": "Between", "inputs": [3, 2]},
|
371 |
+
{"id": 5, "function": "Between", "inputs": [4, 3]}
|
372 |
+
]
|
373 |
+
},
|
374 |
+
{
|
375 |
+
"index": 25,
|
376 |
+
"instruction": "You have been tasked with setting up survey stations around Auckland, New Zealand for a geographical study. Begin by finding a point 6 km southwest of Auckland. Then, find the midpoint between this new point and Auckland. Finally, calculate the midpoint between Auckland and the previously obtained midpoint to determine an optimal survey station location.",
|
377 |
+
"steps": [
|
378 |
+
{"id": 1, "function": "Relative", "inputs": ["Auckland, New Zealand", "southwest", "6 km"]},
|
379 |
+
{"id": 2, "function": "Between", "inputs": ["Auckland, New Zealand", 1]},
|
380 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
381 |
+
]
|
382 |
+
},
|
383 |
+
{
|
384 |
+
"index": 26,
|
385 |
+
"instruction": "Starting from Paris, France, head in the direction of an azimuth of 263° for 8 kilometers. Then find the midpoint between Paris and this new location.",
|
386 |
+
"steps": [
|
387 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Paris, France", "263°", "8 km"]},
|
388 |
+
{"id": 2, "function": "Between", "inputs": ["Paris, France", 1]}
|
389 |
+
]
|
390 |
+
},
|
391 |
+
{
|
392 |
+
"index": 27,
|
393 |
+
"instruction": "Identify potential locations for a new transatlantic transportation hub by calculating the midpoint between New York City and London, UK.",
|
394 |
+
"steps": [
|
395 |
+
{"id": 1, "function": "Between", "inputs": ["New York City", "London, UK"]},
|
396 |
+
{"id": 2, "function": "Between", "inputs": ["New York City", 1]},
|
397 |
+
{"id": 3, "function": "Between", "inputs": ["New York City", 2]},
|
398 |
+
{"id": 4, "function": "Between", "inputs": ["New York City", 3]}
|
399 |
+
]
|
400 |
+
},
|
401 |
+
{
|
402 |
+
"index": 28,
|
403 |
+
"instruction": "Determine the location 6 kilometers east of Shinjuku in Tokyo to explore potential development opportunities for urban expansion.",
|
404 |
+
"steps": [
|
405 |
+
{"id": 1, "function": "Relative", "inputs": ["Shinjuku", "east", "6 km"]}
|
406 |
+
]
|
407 |
+
},
|
408 |
+
{
|
409 |
+
"index": 29,
|
410 |
+
"instruction": "You are planning to set up a strategic tourist information center that serves travelers between Paris and Rome. First, relocate your initial planning position 7 km southwest from the Eiffel Tower. Then find the midpoint between this new location and the Colosseum in Rome to determine a secondary focus area. Finally, calculate the central navigational hub between this focus area and the Colosseum to ensure optimal accessibility for tourists in both major cities.",
|
411 |
+
"steps": [
|
412 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower", "southwest", "7 km"]},
|
413 |
+
{"id": 2, "function": "Between", "inputs": ["Colosseum", 1]},
|
414 |
+
{"id": 3, "function": "Between", "inputs": [2, "Colosseum"]}
|
415 |
+
]
|
416 |
+
},
|
417 |
+
{
|
418 |
+
"index": 30,
|
419 |
+
"instruction": "Calculate the strategic point for logistics by starting from Los Angeles, finding the midpoint to New York City, re-evaluating midpoints twice, and finally moving 9 km north to finalize the location.",
|
420 |
+
"steps": [
|
421 |
+
{"id": 1, "function": "Between", "inputs": ["Los Angeles", "New York City"]},
|
422 |
+
{"id": 2, "function": "Between", "inputs": [1, "New York City"]},
|
423 |
+
{"id": 3, "function": "Relative", "inputs": [2, "north", "9 km"]}
|
424 |
+
]
|
425 |
+
},
|
426 |
+
{
|
427 |
+
"index": 31,
|
428 |
+
"instruction": "Start at Toronto Pearson International Airport. Move 9 km north to locate your initial checkpoint. From there, travel 4 km south to reach your final meeting point for the logistics team.",
|
429 |
+
"steps": [
|
430 |
+
{"id": 1, "function": "Relative", "inputs": ["Toronto Pearson International Airport", "north", "9 km"]},
|
431 |
+
{"id": 2, "function": "Relative", "inputs": [1, "south", "4 km"]}
|
432 |
+
]
|
433 |
+
},
|
434 |
+
{
|
435 |
+
"index": 32,
|
436 |
+
"instruction": "Calculate the midpoint between New York City and Los Angeles, then adjust this point by moving 3 kilometers in the azimuth direction of 51 degrees to find a suitable location for setting up a temporary distribution hub.",
|
437 |
+
"steps": [
|
438 |
+
{"id": 1, "function": "Between", "inputs": ["New York City", "Los Angeles"]},
|
439 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "51°", "3 km"]}
|
440 |
+
]
|
441 |
+
},
|
442 |
+
{
|
443 |
+
"index": 33,
|
444 |
+
"instruction": "Calculate the location that is 9 km southeast from Fort William, which could serve as the next hiking point on your trip in the Scottish Highlands.",
|
445 |
+
"steps": [
|
446 |
+
{"id": 1, "function": "Relative", "inputs": ["Fort William", "southeast", "9 km"]}
|
447 |
+
]
|
448 |
+
},
|
449 |
+
{
|
450 |
+
"index": 34,
|
451 |
+
"instruction": "Start at the Sydney Opera House and head 6 km at an azimuth of 235°. Then move southwest for 1 km to reach the designated location for setting up the research station.",
|
452 |
+
"steps": [
|
453 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "235°", "6 km"]},
|
454 |
+
{"id": 2, "function": "Relative", "inputs": [1, "southwest", "1 km"]}
|
455 |
+
]
|
456 |
+
},
|
457 |
+
{
|
458 |
+
"index": 35,
|
459 |
+
"instruction": "Plan an expedition starting from Honolulu, Hawaii. Move 6 km at a 52° azimuth from Honolulu to find a new location. Then, calculate the midpoint between this location and Honolulu. From this midpoint, travel 8 km at a 103° azimuth to reach the next location on your expedition route.",
|
460 |
+
"steps": [
|
461 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Honolulu", "52°", "6 km"]},
|
462 |
+
{"id": 2, "function": "Between", "inputs": [1, "Honolulu"]},
|
463 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "103°", "8 km"]}
|
464 |
+
]
|
465 |
+
},
|
466 |
+
{
|
467 |
+
"index": 36,
|
468 |
+
"instruction": "For a scientific expedition in Antarctica, navigate approximately 5 km along a 175° azimuth from McMurdo Station. Then, determine the midpoint between the new location and the Amundsen-Scott South Pole Station to plan the location of a temporary research marker.",
|
469 |
+
"steps": [
|
470 |
+
{"id": 1, "function": "Azimuth", "inputs": ["McMurdo Station", "175°", "5 km"]},
|
471 |
+
{"id": 2, "function": "Between", "inputs": [1, "Amundsen-Scott South Pole Station"]}
|
472 |
+
]
|
473 |
+
},
|
474 |
+
{
|
475 |
+
"index": 37,
|
476 |
+
"instruction": "Plan a hiking route starting from Yokohama. First, hike 3 km in the southeast direction at an angle of 105°. From this new location, continue a further 6 km eastwards at 110°. Finally, determine the midpoint between Yokohama and your current location to find an ideal campsite with a good view of the region.",
|
477 |
+
"steps": [
|
478 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Yokohama", "105°", "3 km"]},
|
479 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "110°", "6 km"]},
|
480 |
+
{"id": 3, "function": "Between", "inputs": ["Yokohama", 2]}
|
481 |
+
]
|
482 |
+
},
|
483 |
+
{
|
484 |
+
"index": 38,
|
485 |
+
"instruction": "You are at the Eiffel Tower in Paris. First, travel 7 kilometers southwest to reach a new point. From there, head 9 kilometers north to discover an interesting location for sightseeing.",
|
486 |
+
"steps": [
|
487 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower", "southwest", "7 km"]},
|
488 |
+
{"id": 2, "function": "Relative", "inputs": [1, "north", "9 km"]}
|
489 |
+
]
|
490 |
+
},
|
491 |
+
{
|
492 |
+
"index": 39,
|
493 |
+
"instruction": "Determine the location that is 8 kilometers southeast of Paris, France, for setting up a new survey point.",
|
494 |
+
"steps": [
|
495 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris, France", "southeast", "8 km"]}
|
496 |
+
]
|
497 |
+
},
|
498 |
+
{
|
499 |
+
"index": 40,
|
500 |
+
"instruction": "Determine the optimal location for a wildlife research station by starting from the midpoint between Tromsø, Norway, and Rovaniemi, Finland. Move 10 km north from this midpoint, then find the point that lies midway between this new position and Rovaniemi. Finally, calculate the midpoint between this last point and Rovaniemi to finalize the location of the research station.",
|
501 |
+
"steps": [
|
502 |
+
{"id": 1, "function": "Between", "inputs": ["Tromsø", "Rovaniemi"]},
|
503 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "354°", "10 km"]},
|
504 |
+
{"id": 3, "function": "Between", "inputs": [2, "Rovaniemi"]},
|
505 |
+
{"id": 4, "function": "Between", "inputs": ["Rovaniemi", 3]}
|
506 |
+
]
|
507 |
+
},
|
508 |
+
{
|
509 |
+
"index": 41,
|
510 |
+
"instruction": "Plan a short hiking trip starting from Syntagma Square in Athens, Greece, and head west for approximately 6 kilometers to explore the surroundings.",
|
511 |
+
"steps": [
|
512 |
+
{"id": 1, "function": "Relative", "inputs": ["Syntagma Square, Athens", "west", "6 km"]}
|
513 |
+
]
|
514 |
+
},
|
515 |
+
{
|
516 |
+
"index": 42,
|
517 |
+
"instruction": "Plan a short hiking adventure starting from Sydney, Australia. First, find a point located 8 km to the southwest at an azimuth angle of 228°. Then, determine the midpoint between Sydney and this new location to possibly set up a waypoint for your hike.",
|
518 |
+
"steps": [
|
519 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney, Australia", "228°", "8 km"]},
|
520 |
+
{"id": 2, "function": "Between", "inputs": ["Sydney, Australia", 1]}
|
521 |
+
]
|
522 |
+
},
|
523 |
+
{
|
524 |
+
"index": 43,
|
525 |
+
"instruction": "From the base of the Eiffel Tower, proceed southwest for 2 km to find a quiet spot or meeting point.",
|
526 |
+
"steps": [
|
527 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower", "southwest", "2 km"]}
|
528 |
+
]
|
529 |
+
},
|
530 |
+
{
|
531 |
+
"index": 44,
|
532 |
+
"instruction": "Find a location that is at the midpoint between the Eiffel Tower and a point 2 kilometers north of the Eiffel Tower, then continue to find a midpoint between this location and the Arc de Triomphe in Paris.",
|
533 |
+
"steps": [
|
534 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower", "north", "2 km"]},
|
535 |
+
{"id": 2, "function": "Between", "inputs": ["Eiffel Tower", 1]}
|
536 |
+
]
|
537 |
+
},
|
538 |
+
{
|
539 |
+
"index": 45,
|
540 |
+
"instruction": "Determine the location that is 3 km northeast (67° azimuth) of Tokyo, Japan, to set up a new meteorological research station.",
|
541 |
+
"steps": [
|
542 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Tokyo, Japan", "67°", "3 km"]}
|
543 |
+
]
|
544 |
+
},
|
545 |
+
{
|
546 |
+
"index": 46,
|
547 |
+
"instruction": "Starting from the Christopher Columbus Monument in Barcelona, proceed 1 km at an azimuth of 173° to reach your next sightseeing point on the beach.",
|
548 |
+
"steps": [
|
549 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Christopher Columbus Monument, Barcelona, Spain", "173°", "1 km"]}
|
550 |
+
]
|
551 |
+
},
|
552 |
+
{
|
553 |
+
"index": 47,
|
554 |
+
"instruction": "Identify a suitable midpoint location to set up a communication outpost between Alice Springs and a point 6 km to the east of it.",
|
555 |
+
"steps": [
|
556 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Alice Springs", "94°", "6 km"]},
|
557 |
+
{"id": 2, "function": "Between", "inputs": [1, "Alice Springs"]}
|
558 |
+
]
|
559 |
+
},
|
560 |
+
{
|
561 |
+
"index": 48,
|
562 |
+
"instruction": "You are starting at Fisherman's Wharf in San Francisco. Walk northwest for 2 kilometers to reach the San Francisco Maritime National Historical Park.",
|
563 |
+
"steps": [
|
564 |
+
{"id": 1, "function": "Relative", "inputs": ["Fisherman's Wharf", "northwest", "2 km"]}
|
565 |
+
]
|
566 |
+
},
|
567 |
+
{
|
568 |
+
"index": 49,
|
569 |
+
"instruction": "You are planning an exploratory session starting from the Sydney Opera House. First, navigate 2 km southwest to reach a new area in Sydney. Then, from there, travel 2 km north. Finally, find the midpoint between St Kilda Beach in Melbourne and your latest location to identify a central meeting or station setup point.",
|
570 |
+
"steps": [
|
571 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "232°", "2 km"]},
|
572 |
+
{"id": 2, "function": "Relative", "inputs": [1, "north", "2 km"]},
|
573 |
+
{"id": 3, "function": "Between", "inputs": ["St Kilda Beach", 2]}
|
574 |
+
]
|
575 |
+
},
|
576 |
+
{
|
577 |
+
"index": 50,
|
578 |
+
"instruction": "You're leading an archaeological expedition and starting the journey from Luxor, Egypt. First, move 6 km at an azimuth of 121° to a new exploration site. Simultaneously, from the Valley of the Kings, head 9 km northeast, and then adjust your path 3 km to the southeast. Finally, find the midpoint between your moved positions to establish a central base camp for the expedition.",
|
579 |
+
"steps": [
|
580 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Luxor", "121°", "6 km"]},
|
581 |
+
{"id": 2, "function": "Relative", "inputs": ["Valley of the Kings", "northeast", "9 km"]},
|
582 |
+
{"id": 3, "function": "Relative", "inputs": [2, "southeast", "3 km"]},
|
583 |
+
{"id": 4, "function": "Between", "inputs": [1, 3]}
|
584 |
+
]
|
585 |
+
},
|
586 |
+
{
|
587 |
+
"index": 51,
|
588 |
+
"instruction": "Plan a short exploration route by first identifying a location approximately 5 km northwest of the center of Paris, then calculate the midpoint between this northwest point and Paris itself, and finally find the central location between the two previously identified midpoints.",
|
589 |
+
"steps": [
|
590 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris, France", "northwest", "5 km"]},
|
591 |
+
{"id": 2, "function": "Between", "inputs": [1, "Paris, France"]},
|
592 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
593 |
+
]
|
594 |
+
},
|
595 |
+
{
|
596 |
+
"index": 52,
|
597 |
+
"instruction": "Determine the optimal location for a communication relay station by first finding the midpoint between the Eiffel Tower in Paris and the Brandenburg Gate in Berlin. From this midpoint, move 1 kilometer at an azimuth angle of 15° to finalize the station's position.",
|
598 |
+
"steps": [
|
599 |
+
{"id": 1, "function": "Between", "inputs": ["Eiffel Tower", "Brandenburg Gate"]},
|
600 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "15°", "1 km"]}
|
601 |
+
]
|
602 |
+
},
|
603 |
+
{
|
604 |
+
"index": 53,
|
605 |
+
"instruction": "Calculate the midpoint for a new research station between 10 km south of Mendoza, Argentina and Santiago, Chile.",
|
606 |
+
"steps": [
|
607 |
+
{"id": 1, "function": "Relative", "inputs": ["Mendoza, Argentina", "south", "10 km"]},
|
608 |
+
{"id": 2, "function": "Between", "inputs": [1, "Santiago, Chile"]}
|
609 |
+
]
|
610 |
+
},
|
611 |
+
{
|
612 |
+
"index": 54,
|
613 |
+
"instruction": "Begin your exploration at the Eiffel Tower in Paris. Move 1 km east from the Eiffel Tower, then find the midpoint between the Eiffel Tower and the location 1 km east. Next, identify the midpoint between this new midpoint and the Eiffel Tower.",
|
614 |
+
"steps": [
|
615 |
+
{"id": 1, "function": "Relative", "inputs": ["Eiffel Tower, Paris, France", "east", "1 km"]},
|
616 |
+
{"id": 2, "function": "Between", "inputs": ["Eiffel Tower, Paris, France", 1]},
|
617 |
+
{"id": 3, "function": "Between", "inputs": [2, "Eiffel Tower, Paris, France"]}
|
618 |
+
]
|
619 |
+
},
|
620 |
+
{
|
621 |
+
"index": 55,
|
622 |
+
"instruction": "From the Eiffel Tower in Paris, navigate west-southwest for 9 kilometers to reach a unique destination ideal for a day trip or outdoor exploration.",
|
623 |
+
"steps": [
|
624 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Eiffel Tower, Paris, France", "252°", "9 km"]}
|
625 |
+
]
|
626 |
+
},
|
627 |
+
{
|
628 |
+
"index": 56,
|
629 |
+
"instruction": "Begin your sailing route from Signal Hill in Cape Town. Move in a direction of 76° (northeast) from this landmark for 2 kilometers into the ocean. Then alter your course to proceed 10 kilometers southeast to reach your specified destination point off the coastal waters of Cape Town.",
|
630 |
+
"steps": [
|
631 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Signal Hill, Cape Town", "76°", "2 km"]},
|
632 |
+
{"id": 2, "function": "Relative", "inputs": [1, "southeast", "10 km"]}
|
633 |
+
]
|
634 |
+
},
|
635 |
+
{
|
636 |
+
"index": 57,
|
637 |
+
"instruction": "Determine the new region located 3 kilometers southwest of Berlin, Germany, to set up a temporary monitoring station for the eco-study project.",
|
638 |
+
"steps": [
|
639 |
+
{"id": 1, "function": "Relative", "inputs": ["Berlin, Germany", "southwest", "3 km"]}
|
640 |
+
]
|
641 |
+
},
|
642 |
+
{
|
643 |
+
"index": 58,
|
644 |
+
"instruction": "Begin at Times Square in New York City. First, move 8 km in the direction of 161°. From that location, continue moving 2 km in the direction of 69°. Find the midpoint between the previous two points. Finally, calculate the midpoint between this latest point and Times Square.",
|
645 |
+
"steps": [
|
646 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Times Square, New York City", "161°", "8 km"]},
|
647 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "69°", "2 km"]},
|
648 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
649 |
+
{"id": 4, "function": "Between", "inputs": [3, "Times Square, New York City"]}
|
650 |
+
]
|
651 |
+
},
|
652 |
+
{
|
653 |
+
"index": 59,
|
654 |
+
"instruction": "Plan a hiking meeting point by first moving 4 km north (at 13° azimuth) from Banff National Park. Then, find the midpoint between this new location and Jasper National Park. Determine the optimal final meeting location by finding the midpoint between the point from the previous step and Banff National Park.",
|
655 |
+
"steps": [
|
656 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Banff National Park", "13°", "4 km"]},
|
657 |
+
{"id": 2, "function": "Between", "inputs": ["Jasper National Park", 1]},
|
658 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
659 |
+
]
|
660 |
+
},
|
661 |
+
{
|
662 |
+
"index": 60,
|
663 |
+
"instruction": "Determine an optimal location for a new wildlife observation post in the Yellowstone National Park. From the Yellowstone National Park Ranger Station, explore 3 km at an azimuth of 222° to find one potential point. Then, explore 8 km at an azimuth of 102° to find another potential point. Finally, determine the midpoint between these two points, which will serve as a strategic location for the observation post.",
|
664 |
+
"steps": [
|
665 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Yellowstone National Park Ranger Station", "222°", "3 km"]},
|
666 |
+
{"id": 2, "function": "Azimuth", "inputs": ["Yellowstone National Park Ranger Station", "102°", "8 km"]},
|
667 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
668 |
+
]
|
669 |
+
},
|
670 |
+
{
|
671 |
+
"index": 61,
|
672 |
+
"instruction": "Plan the placement of emergency response stations starting from Sydney, Australia. First, navigate 6 km southeast to set an initial station. Calculate the midpoint between this new location and Sydney to determine a focal area. Extend from this midpoint 10 km to the northeast for additional coverage. Finally, finalize the main station location by finding a midpoint and making a slight adjustment 2 km to the west.",
|
673 |
+
"steps": [
|
674 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney, Australia", "155°", "6 km"]},
|
675 |
+
{"id": 2, "function": "Between", "inputs": ["Sydney, Australia", 1]},
|
676 |
+
{"id": 3, "function": "Relative", "inputs": [2, "northeast", "10 km"]},
|
677 |
+
{"id": 4, "function": "Between", "inputs": ["Sydney, Australia", 3]},
|
678 |
+
{"id": 5, "function": "Azimuth", "inputs": [4, "253°", "2 km"]}
|
679 |
+
]
|
680 |
+
},
|
681 |
+
{
|
682 |
+
"index": 62,
|
683 |
+
"instruction": "Starting from the Eiffel Tower in Paris, France, calculate the location by moving 7 km in the direction of 335°, and then move 1 km to the west from there. This will assist in laying out the final position for setting up a temporary logistical base for a community event.",
|
684 |
+
"steps": [
|
685 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Eiffel Tower", "335°", "7 km"]},
|
686 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "1 km"]}
|
687 |
+
]
|
688 |
+
},
|
689 |
+
{
|
690 |
+
"index": 63,
|
691 |
+
"instruction": "To set up a research field station, start from Yellowstone National Park. First, move 8 km westward to position the main base. Then, proceed to establish an outpost 6 km away in the direction of 209° from the new base location.",
|
692 |
+
"steps": [
|
693 |
+
{"id": 1, "function": "Relative", "inputs": ["Yellowstone National Park", "west", "8 km"]},
|
694 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "209°", "6 km"]}
|
695 |
+
]
|
696 |
+
},
|
697 |
+
{
|
698 |
+
"index": 64,
|
699 |
+
"instruction": "From Denali National Park, move 7 km northeast, then find the midpoint between this new location and Denali National Park itself.",
|
700 |
+
"steps": [
|
701 |
+
{"id": 1, "function": "Relative", "inputs": ["Denali National Park", "northeast", "7 km"]},
|
702 |
+
{"id": 2, "function": "Between", "inputs": [1, "Denali National Park"]}
|
703 |
+
]
|
704 |
+
},
|
705 |
+
{
|
706 |
+
"index": 65,
|
707 |
+
"instruction": "Set up a route for a geological survey team starting from Timbuktu, Mali. First, locate a point 5 km away from Timbuktu, at an azimuth of 104 degrees. Then find the midpoint between Timbuktu and this new point for a preliminary survey site. Next, calculate another midpoint on this path for an extended survey. Finally, from this extended point, navigate 10 km southeast to establish the primary weather monitoring station site.",
|
708 |
+
"steps": [
|
709 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Timbuktu, Mali", "104°", "5 km"]},
|
710 |
+
{"id": 2, "function": "Between", "inputs": [1, "Timbuktu, Mali"]},
|
711 |
+
{"id": 3, "function": "Between", "inputs": ["Timbuktu, Mali", 2]},
|
712 |
+
{"id": 4, "function": "Azimuth", "inputs": [3, "117°", "10 km"]}
|
713 |
+
]
|
714 |
+
},
|
715 |
+
{
|
716 |
+
"index": 66,
|
717 |
+
"instruction": "Start at the city center of Cambridge and move 9 kilometers in the direction of 248° to reach your destination near Great Shelford.",
|
718 |
+
"steps": [
|
719 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Cambridge", "248°", "9 km"]}
|
720 |
+
]
|
721 |
+
},
|
722 |
+
{
|
723 |
+
"index": 67,
|
724 |
+
"instruction": "Starting from Monument Valley, travel 10 kilometers at an angle of 124° to identify your new location. Then, from there, navigate 6 kilometers in the northeast direction to reach your final destination.",
|
725 |
+
"steps": [
|
726 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Monument Valley, Arizona", "124°", "10 km"]},
|
727 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "6 km"]}
|
728 |
+
]
|
729 |
+
},
|
730 |
+
{
|
731 |
+
"index": 68,
|
732 |
+
"instruction": "Start your journey at Central Park, New York. Travel 9 kilometers southeast to reach the area around Midwood, Brooklyn. Then, head 7 kilometers northwest towards the vicinity of Williamsburg, completing your urban exploration.",
|
733 |
+
"steps": [
|
734 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, New York", "southeast", "9 km"]},
|
735 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northwest", "7 km"]}
|
736 |
+
]
|
737 |
+
},
|
738 |
+
{
|
739 |
+
"index": 69,
|
740 |
+
"instruction": "Determine the geographical midpoint between Cape Town, South Africa, and Antananarivo, Madagascar, for potential setup of a meeting point for the expedition.",
|
741 |
+
"steps": [
|
742 |
+
{"id": 1, "function": "Between", "inputs": ["Cape Town, South Africa", "Antananarivo, Madagascar"]},
|
743 |
+
{"id": 2, "function": "Between", "inputs": ["Cape Town, South Africa", 1]}
|
744 |
+
]
|
745 |
+
},
|
746 |
+
{
|
747 |
+
"index": 70,
|
748 |
+
"instruction": "Calculate the midpoint between Rio de Janeiro and Buenos Aires, and then find the midpoint between São Paulo and the result from the first calculation. These locations can help in planning stopovers during a trip from Brazil to Argentina.",
|
749 |
+
"steps": [
|
750 |
+
{"id": 1, "function": "Between", "inputs": ["Rio de Janeiro", "Buenos Aires"]},
|
751 |
+
{"id": 2, "function": "Between", "inputs": ["São Paulo", 1]}
|
752 |
+
]
|
753 |
+
},
|
754 |
+
{
|
755 |
+
"index": 71,
|
756 |
+
"instruction": "Starting from Newbury, first move 8 km northeast to determine a new location. From Newbury again, go 7 km south to find another point. Then, from the first new location, move 8 km at an angle of 297° to discover a third point. Finally, locate the midpoint between the third and the second points calculated to determine an ideal location for setting up a temporary research station.",
|
757 |
+
"steps": [
|
758 |
+
{"id": 1, "function": "Relative", "inputs": ["Newbury", "northeast", "8 km"]},
|
759 |
+
{"id": 2, "function": "Relative", "inputs": ["Newbury", "south", "7 km"]},
|
760 |
+
{"id": 3, "function": "Azimuth", "inputs": [1, "297°", "8 km"]},
|
761 |
+
{"id": 4, "function": "Between", "inputs": [3, 2]}
|
762 |
+
]
|
763 |
+
},
|
764 |
+
{
|
765 |
+
"index": 72,
|
766 |
+
"instruction": "Determine the midpoint for setting up a potential urban outdoor event area, starting from Central Park, New York City. First, calculate the midpoint between a location 8 km north and another 2 km northeast of Central Park. Then, find the midpoint between this result and a further point 10 km north of Central Park.",
|
767 |
+
"steps": [
|
768 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, New York City", "north", "8 km"]},
|
769 |
+
{"id": 2, "function": "Relative", "inputs": ["Central Park, New York City", "northeast", "2 km"]},
|
770 |
+
{"id": 3, "function": "Relative", "inputs": ["Central Park, New York City", "north", "10 km"]},
|
771 |
+
{"id": 4, "function": "Between", "inputs": [1, 2]},
|
772 |
+
{"id": 5, "function": "Between", "inputs": [3, 4]}
|
773 |
+
]
|
774 |
+
},
|
775 |
+
{
|
776 |
+
"index": 73,
|
777 |
+
"instruction": "Starting from Tokyo Tower, Tokyo, project a new location that lies 8 kilometers to the southeast (136°). Then, determine the midpoint between Tokyo Tower and this new location for planning purposes.",
|
778 |
+
"steps": [
|
779 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Tokyo Tower, Tokyo, Japan", "136°", "8 km"]},
|
780 |
+
{"id": 2, "function": "Between", "inputs": [1, "Tokyo Tower, Tokyo, Japan"]}
|
781 |
+
]
|
782 |
+
},
|
783 |
+
{
|
784 |
+
"index": 74,
|
785 |
+
"instruction": "Calculate a new point that is 1 km away from Sydney, Australia, towards the south-southeast at an azimuth of 155°. Then, find the midpoint between the original location in Sydney and this new point.",
|
786 |
+
"steps": [
|
787 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney, Australia", "155°", "1 km"]},
|
788 |
+
{"id": 2, "function": "Between", "inputs": [1, "Sydney, Australia"]}
|
789 |
+
]
|
790 |
+
},
|
791 |
+
{
|
792 |
+
"index": 75,
|
793 |
+
"instruction": "You are tasked with planning survey checkpoints in the Mont Blanc region. Start in Courmayeur, Italy, moving 1 km northwest. Then, find a midpoint between Courmayeur and Chamonix, France. From that midpoint, traverse 7 km southeast at an azimuth of 111°. Next, adjust your path 9 km northeasterly at an azimuth of 39°. Ultimately, head 10 km southwest to identify the survey area's final checkpoint.",
|
794 |
+
"steps": [
|
795 |
+
{"id": 1, "function": "Relative", "inputs": ["Courmayeur", "northwest", "1 km"]},
|
796 |
+
{"id": 2, "function": "Between", "inputs": ["Chamonix", 1]},
|
797 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "111°", "7 km"]},
|
798 |
+
{"id": 4, "function": "Azimuth", "inputs": [3, "39°", "9 km"]},
|
799 |
+
{"id": 5, "function": "Relative", "inputs": [4, "southwest", "10 km"]}
|
800 |
+
]
|
801 |
+
},
|
802 |
+
{
|
803 |
+
"index": 76,
|
804 |
+
"instruction": "Determine the location that lies 1 km to the southeast of Union Square, San Francisco, for setting up a pop-up event.",
|
805 |
+
"steps": [
|
806 |
+
{"id": 1, "function": "Relative", "inputs": ["Union Square, San Francisco", "southeast", "1 km"]}
|
807 |
+
]
|
808 |
+
},
|
809 |
+
{
|
810 |
+
"index": 77,
|
811 |
+
"instruction": "Plan a short hike starting from Sapporo, Japan. First, move 2 kilometers northeast. Then, find the midpoint between your initial location in Sapporo and the location after moving 2 kilometers northeast. This midpoint is where you can schedule a rest stop.",
|
812 |
+
"steps": [
|
813 |
+
{"id": 1, "function": "Relative", "inputs": ["Sapporo", "northeast", "2 km"]},
|
814 |
+
{"id": 2, "function": "Between", "inputs": ["Sapporo", 1]}
|
815 |
+
]
|
816 |
+
},
|
817 |
+
{
|
818 |
+
"index": 78,
|
819 |
+
"instruction": "You are planning a day trip from Paris to explore and want to find a mid-point between Versailles and a point 1 km away at 16° northward. Use these coordinates to decide where to have a quick coffee break on your excursion.",
|
820 |
+
"steps": [
|
821 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Versailles", "16°", "1 km"]},
|
822 |
+
{"id": 2, "function": "Between", "inputs": [1, "Versailles"]}
|
823 |
+
]
|
824 |
+
},
|
825 |
+
{
|
826 |
+
"index": 79,
|
827 |
+
"instruction": "Calculate a new starting point for a hiking trip by moving 6 kilometers northwest from Boulder, Colorado.",
|
828 |
+
"steps": [
|
829 |
+
{"id": 1, "function": "Relative", "inputs": ["Boulder, Colorado", "northwest", "6 km"]}
|
830 |
+
]
|
831 |
+
},
|
832 |
+
{
|
833 |
+
"index": 80,
|
834 |
+
"instruction": "Identify the location 5 km in the direction of 294° from the Eiffel Tower in Paris.",
|
835 |
+
"steps": [
|
836 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Eiffel Tower, Paris", "294°", "5 km"]}
|
837 |
+
]
|
838 |
+
},
|
839 |
+
{
|
840 |
+
"index": 81,
|
841 |
+
"instruction": "Plan a network of reference stations by first moving 5 km south-southwest from Rio de Janeiro, then calculate a sequence of midpoints, and finalize the position by moving 3 km north-northeast from the last midpoint for setting up the light tower.",
|
842 |
+
"steps": [
|
843 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Rio de Janeiro", "256°", "5 km"]},
|
844 |
+
{"id": 2, "function": "Between", "inputs": ["Rio de Janeiro", 1]},
|
845 |
+
{"id": 3, "function": "Between", "inputs": [2, "Rio de Janeiro"]},
|
846 |
+
{"id": 4, "function": "Between", "inputs": [2, 3]},
|
847 |
+
{"id": 5, "function": "Azimuth", "inputs": [4, "25°", "3 km"]}
|
848 |
+
]
|
849 |
+
},
|
850 |
+
{
|
851 |
+
"index": 82,
|
852 |
+
"instruction": "Determine a new location 6 km southeast of Florence, then find the midpoint between Florence and this new location.",
|
853 |
+
"steps": [
|
854 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Florence, Italy", "125°", "6 km"]},
|
855 |
+
{"id": 2, "function": "Between", "inputs": ["Florence, Italy", 1]}
|
856 |
+
]
|
857 |
+
},
|
858 |
+
{
|
859 |
+
"index": 83,
|
860 |
+
"instruction": "Start your hike from Aoraki / Mount Cook. Begin by heading in a direction of 141° for a distance of 8 km. Once you reach the new position, find your mid-point back towards Aoraki / Mount Cook to ensure you're along the correct path. From this midpoint, head 60° for 10 km to reach another scenic destination.",
|
861 |
+
"steps": [
|
862 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Aoraki / Mount Cook", "141°", "8 km"]},
|
863 |
+
{"id": 2, "function": "Between", "inputs": [1, "Aoraki / Mount Cook"]},
|
864 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "60°", "10 km"]}
|
865 |
+
]
|
866 |
+
},
|
867 |
+
{
|
868 |
+
"index": 84,
|
869 |
+
"instruction": "Starting from the Christ the Redeemer statue in Rio de Janeiro, plan an expedition that initially moves 3 kilometers in the direction of 136°, adjusts course to head 4 kilometers north, and subsequently proceeds 5 kilometers at an azimuth of 3°. Document the key positions along this route.",
|
870 |
+
"steps": [
|
871 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Christ the Redeemer, Rio de Janeiro, Brazil", "136°", "3 km"]},
|
872 |
+
{"id": 2, "function": "Relative", "inputs": [1, "north", "4 km"]},
|
873 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "3°", "5 km"]}
|
874 |
+
]
|
875 |
+
},
|
876 |
+
{
|
877 |
+
"index": 85,
|
878 |
+
"instruction": "Calculate an optimal central location for an international conference by considering midpoints first between New York City and London, and then including Sydney in the balancing. Ultimately, find a point that is equally convenient for attendees from all three cities.",
|
879 |
+
"steps": [
|
880 |
+
{"id": 1, "function": "Between", "inputs": ["New York City", "London"]},
|
881 |
+
{"id": 2, "function": "Between", "inputs": [1, "Sydney"]},
|
882 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
883 |
+
]
|
884 |
+
},
|
885 |
+
{
|
886 |
+
"index": 86,
|
887 |
+
"instruction": "Starting from the southern boundary of Central Park in New York City, hike 4 kilometers north to reach the vicinity of the Jacqueline Kennedy Onassis Reservoir. From there, continue 1 kilometer east to arrive close to the park's eastern edge for a scenic viewpoint.",
|
888 |
+
"steps": [
|
889 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park South, New York City", "north", "4 km"]},
|
890 |
+
{"id": 2, "function": "Relative", "inputs": [1, "east", "1 km"]}
|
891 |
+
]
|
892 |
+
},
|
893 |
+
{
|
894 |
+
"index": 87,
|
895 |
+
"instruction": "Find a location for a hiking trail that is approximately 8 kilometers northwest of San Francisco city center.",
|
896 |
+
"steps": [
|
897 |
+
{"id": 1, "function": "Relative", "inputs": ["San Francisco, CA", "northwest", "8 km"]}
|
898 |
+
]
|
899 |
+
},
|
900 |
+
{
|
901 |
+
"index": 88,
|
902 |
+
"instruction": "Starting from the Sydney Opera House, travel 7 kilometers in a direction of 172 degrees. Then, find the midpoint between the Sydney Opera House and your current position.",
|
903 |
+
"steps": [
|
904 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "172°", "7 km"]},
|
905 |
+
{"id": 2, "function": "Between", "inputs": ["Sydney Opera House", 1]}
|
906 |
+
]
|
907 |
+
},
|
908 |
+
{
|
909 |
+
"index": 89,
|
910 |
+
"instruction": "Start your journey at Praça do Comércio in Lisbon, Portugal, and travel 3 kilometers towards the west to explore the city's landscape and attractions.",
|
911 |
+
"steps": [
|
912 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Praça do Comércio, Lisbon", "264°", "3 km"]}
|
913 |
+
]
|
914 |
+
},
|
915 |
+
{
|
916 |
+
"index": 90,
|
917 |
+
"instruction": "Start your day trip at the Sydney Opera House and head 7 kilometers in a 175° direction to explore new sights in Sydney.",
|
918 |
+
"steps": [
|
919 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "175°", "7 km"]}
|
920 |
+
]
|
921 |
+
},
|
922 |
+
{
|
923 |
+
"index": 91,
|
924 |
+
"instruction": "Start your journey in Central Park, New York. Head 4 kilometers to the east, and then find the midpoint between your new location and Times Square to identify your next stop.",
|
925 |
+
"steps": [
|
926 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, NY", "east", "4 km"]},
|
927 |
+
{"id": 2, "function": "Between", "inputs": [1, "Times Square, NY"]}
|
928 |
+
]
|
929 |
+
},
|
930 |
+
{
|
931 |
+
"index": 92,
|
932 |
+
"instruction": "You are planning a hiking route starting from Golden Gate Park in San Francisco. Head southwest for 1 km to reach the first waypoint. From there, travel 2 km at an azimuth of 200° to your second waypoint. Finally, continue 3 km at an azimuth of 303° to your final destination.",
|
933 |
+
"steps": [
|
934 |
+
{"id": 1, "function": "Relative", "inputs": ["Golden Gate Park", "southwest", "1 km"]},
|
935 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "200°", "2 km"]},
|
936 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "303°", "3 km"]}
|
937 |
+
]
|
938 |
+
},
|
939 |
+
{
|
940 |
+
"index": 93,
|
941 |
+
"instruction": "You are planning to explore Paris starting from the Eiffel Tower. First, head southwest for 1 kilometer from the Eiffel Tower. Then, consider traveling 10 kilometers north from the Eiffel Tower towards Enghien-les-Bains. Finally, identify a midpoint between these two exploratory points to discover an interesting location.",
|
942 |
+
"steps": [
|
943 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Eiffel Tower, Paris", "236°", "1 km"]},
|
944 |
+
{"id": 2, "function": "Relative", "inputs": ["Eiffel Tower, Paris", "north", "10 km"]},
|
945 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
946 |
+
]
|
947 |
+
},
|
948 |
+
{
|
949 |
+
"index": 94,
|
950 |
+
"instruction": "Determine the ideal location for a new wildlife observation post between the central Serengeti and a point 6 km southwest of a chosen landmark in the Ngorongoro Conservation Area.",
|
951 |
+
"steps": [
|
952 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Ngorongoro Conservation Area", "217°", "6 km"]},
|
953 |
+
{"id": 2, "function": "Between", "inputs": ["Serengeti National Park", 1]}
|
954 |
+
]
|
955 |
+
},
|
956 |
+
{
|
957 |
+
"index": 95,
|
958 |
+
"instruction": "Start your exploration at Cancun, Mexico. First, proceed 9 km at an azimuth of 182° to reach the initial site. Then, continue further south for 7 km. This journey will position you near potential sites for geological investigation of the Yucatan's unique cenotes.",
|
959 |
+
"steps": [
|
960 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Cancun, Mexico", "182°", "9 km"]},
|
961 |
+
{"id": 2, "function": "Relative", "inputs": [1, "south", "7 km"]}
|
962 |
+
]
|
963 |
+
},
|
964 |
+
{
|
965 |
+
"index": 96,
|
966 |
+
"instruction": "Plan a journey starting from Dublin. Travel southeast for 5 km, then adjust your path to head approximately northwest at an angle of 301° for 9 km. Determine the central point between your initial and final locations after these movements for optimal observation or exploration setup.",
|
967 |
+
"steps": [
|
968 |
+
{"id": 1, "function": "Relative", "inputs": ["Dublin", "southeast", "5 km"]},
|
969 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "301°", "9 km"]},
|
970 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
971 |
+
]
|
972 |
+
},
|
973 |
+
{
|
974 |
+
"index": 97,
|
975 |
+
"instruction": "Start at the Sydney Opera House. Travel 8 km southeast at an angle of 165° to identify Point A. Then travel 9 km east-southeast at an angle of 121° to locate Point B. Find the midpoint between these two identified locations for a potential central survey site.",
|
976 |
+
"steps": [
|
977 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Sydney Opera House", "165°", "8 km"]},
|
978 |
+
{"id": 2, "function": "Azimuth", "inputs": ["Sydney Opera House", "121°", "9 km"]},
|
979 |
+
{"id": 3, "function": "Between", "inputs": [2, 1]}
|
980 |
+
]
|
981 |
+
},
|
982 |
+
{
|
983 |
+
"index": 98,
|
984 |
+
"instruction": "Starting from Rome, Italy, proceed in the direction of 345° for 9 kilometers to reach a location to the north-northwest of the city for observation purposes.",
|
985 |
+
"steps": [
|
986 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Rome, Italy", "345°", "9 km"]}
|
987 |
+
]
|
988 |
+
},
|
989 |
+
{
|
990 |
+
"index": 99,
|
991 |
+
"instruction": "Establish two new weather monitoring stations in a southwest direction starting from Shibuya, Tokyo. The first station should be 4 km southwest of Shibuya, and the second station should be an additional 9 km southwest from the first station.",
|
992 |
+
"steps": [
|
993 |
+
{"id": 1, "function": "Relative", "inputs": ["Shibuya, Tokyo", "southwest", "4 km"]},
|
994 |
+
{"id": 2, "function": "Relative", "inputs": [1, "southwest", "9 km"]}
|
995 |
+
]
|
996 |
+
},
|
997 |
+
{
|
998 |
+
"index": 9,
|
999 |
+
"instruction": "Plan a central spot for a camping trip by first finding the midpoint between Mont Blanc and Matterhorn, then find the midpoint between this point and Chamonix to refine the camping location.",
|
1000 |
+
"steps": [
|
1001 |
+
{"id": 1, "function": "Between", "inputs": ["Mont Blanc", "Matterhorn"]},
|
1002 |
+
{"id": 2, "function": "Between", "inputs": [1, "Chamonix"]}
|
1003 |
+
]
|
1004 |
+
}
|
1005 |
+
]
|
dataset/dataset_10_2.json
ADDED
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"index": 1,
|
4 |
+
"instruction": "You are a wildlife biologist conducting a long-term ecological monitoring study in Tasmania, Australia. You are currently selecting a new observation point between two base areas: Cradle Mountain and Lake St Clair. You plan to move 3 km southwest of Lake St Clair to set up a temporary observation point. You then need to perform a series of spatial calculations: first find a midpoint between this temporary point and Lake St Clair, then find another midpoint between Cradle Mountain and the midpoint of the temporary point, and finally find the final monitoring station location between the first two midpoints. Follow these steps to determine the final location.",
|
5 |
+
"steps": [
|
6 |
+
{"id": 1, "function": "Between", "inputs": ["LOC_2", "LOC_1"]},
|
7 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_2"]}
|
8 |
+
]
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"index": 2,
|
12 |
+
"instruction": "",
|
13 |
+
"steps": [
|
14 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_2", "southeast", "3 km"]},
|
15 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_1"]}
|
16 |
+
]
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"index": 3,
|
20 |
+
"instruction": "",
|
21 |
+
"steps": [
|
22 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "west", "8 km"]},
|
23 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "9 km"]}
|
24 |
+
]
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"index": 4,
|
28 |
+
"instruction": "",
|
29 |
+
"steps": [
|
30 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "25°", "8 km"]},
|
31 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "2 km"]}
|
32 |
+
]
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"index": 5,
|
36 |
+
"instruction": "",
|
37 |
+
"steps": [
|
38 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "36°", "4 km"]},
|
39 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_2", 1]}
|
40 |
+
]
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"index": 6,
|
44 |
+
"instruction": "",
|
45 |
+
"steps": [
|
46 |
+
{"id": 1, "function": "Between", "inputs": ["LOC_2", "LOC_1"]},
|
47 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "266°", "8 km"]}
|
48 |
+
]
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"index": 7,
|
52 |
+
"instruction": "",
|
53 |
+
"steps": [
|
54 |
+
{"id": 1, "function": "Between", "inputs": ["LOC_1", "LOC_2"]},
|
55 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "220°", "8 km"]}
|
56 |
+
]
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"index": 8,
|
60 |
+
"instruction": "",
|
61 |
+
"steps": [
|
62 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "south", "9 km"]},
|
63 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_1", 1]},
|
64 |
+
{"id": 3, "function": "Relative", "inputs": [1, "south", "1 km"]},
|
65 |
+
{"id": 4, "function": "Azimuth", "inputs": [2, "150°", "5 km"]},
|
66 |
+
{"id": 5, "function": "Between", "inputs": [3, 4]}
|
67 |
+
]
|
68 |
+
},
|
69 |
+
{
|
70 |
+
"index": 9,
|
71 |
+
"instruction": "",
|
72 |
+
"steps": [
|
73 |
+
{"id": 1, "function": "Between", "inputs": ["LOC_1", "LOC_2"]},
|
74 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_3"]}
|
75 |
+
]
|
76 |
+
},
|
77 |
+
{
|
78 |
+
"index": 10,
|
79 |
+
"instruction": "",
|
80 |
+
"steps": [
|
81 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "215°", "9 km"]},
|
82 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "99°", "7 km"]},
|
83 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "285°", "1 km"]}
|
84 |
+
]
|
85 |
+
},
|
86 |
+
{
|
87 |
+
"index": 11,
|
88 |
+
"instruction": "",
|
89 |
+
"steps": [
|
90 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "east", "3 km"]},
|
91 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_1"]}
|
92 |
+
]
|
93 |
+
},
|
94 |
+
{
|
95 |
+
"index": 12,
|
96 |
+
"instruction": "",
|
97 |
+
"steps": [
|
98 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "southeast", "9 km"]}
|
99 |
+
]
|
100 |
+
},
|
101 |
+
{
|
102 |
+
"index": 13,
|
103 |
+
"instruction": "",
|
104 |
+
"steps": [
|
105 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "north", "6 km"]},
|
106 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "3°", "5 km"]},
|
107 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "199°", "3 km"]},
|
108 |
+
{"id": 4, "function": "Between", "inputs": [3, "LOC_1"]}
|
109 |
+
]
|
110 |
+
},
|
111 |
+
{
|
112 |
+
"index": 14,
|
113 |
+
"instruction": "",
|
114 |
+
"steps": [
|
115 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "northwest", "2 km"]},
|
116 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "4 km"]},
|
117 |
+
{"id": 3, "function": "Between", "inputs": ["LOC_1", 2]}
|
118 |
+
]
|
119 |
+
},
|
120 |
+
{
|
121 |
+
"index": 15,
|
122 |
+
"instruction": "",
|
123 |
+
"steps": [
|
124 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "northeast", "2 km"]},
|
125 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "333°", "7 km"]},
|
126 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "62°", "9 km"]}
|
127 |
+
]
|
128 |
+
},
|
129 |
+
{
|
130 |
+
"index": 16,
|
131 |
+
"instruction": "",
|
132 |
+
"steps": [
|
133 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "east", "5 km"]}
|
134 |
+
]
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"index": 17,
|
138 |
+
"instruction": "",
|
139 |
+
"steps": [
|
140 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_2", "southwest", "3 km"]},
|
141 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_2"]},
|
142 |
+
{"id": 3, "function": "Between", "inputs": ["LOC_1", 1]},
|
143 |
+
{"id": 4, "function": "Between", "inputs": [2, 3]}
|
144 |
+
]
|
145 |
+
},
|
146 |
+
{
|
147 |
+
"index": 18,
|
148 |
+
"instruction": "",
|
149 |
+
"steps": [
|
150 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "north", "1 km"]},
|
151 |
+
{"id": 2, "function": "Between", "inputs": [1, "LOC_1"]},
|
152 |
+
{"id": 3, "function": "Between", "inputs": ["LOC_1", 2]}
|
153 |
+
]
|
154 |
+
},
|
155 |
+
{
|
156 |
+
"index": 19,
|
157 |
+
"instruction": "",
|
158 |
+
"steps": [
|
159 |
+
{"id": 1, "function": "Azimuth", "inputs": ["LOC_1", "65°", "4 km"]},
|
160 |
+
{"id": 2, "function": "Between", "inputs": ["LOC_1", 1]},
|
161 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "184°", "7 km"]}
|
162 |
+
]
|
163 |
+
},
|
164 |
+
{
|
165 |
+
"index": 20,
|
166 |
+
"instruction": "",
|
167 |
+
"steps": [
|
168 |
+
{"id": 1, "function": "Relative", "inputs": ["LOC_1", "northwest", "10 km"]}
|
169 |
+
]
|
170 |
+
}
|
171 |
+
]
|
dataset/dataset_20.json
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
|
3 |
+
{
|
4 |
+
"index": 1,
|
5 |
+
"instruction": "Plan a trip that involves determining the midpoint between Paris and London, and then finding another midpoint between this location and Paris to identify potential stopovers during travel.",
|
6 |
+
"steps": [
|
7 |
+
{"id": 1, "function": "Between", "inputs": ["Paris, France", "London, England"]},
|
8 |
+
{"id": 2, "function": "Between", "inputs": [1, "Paris, France"]}
|
9 |
+
]
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"index": 2,
|
13 |
+
"instruction": "Imagine you are planning a picnic hike in the Blue Mountains of Australia. Start your hike in Katoomba, move southeast for 3 kilometers, and then find a scenic midpoint between your new location and Echo Point to set up your picnic.",
|
14 |
+
"steps": [
|
15 |
+
{"id": 1, "function": "Relative", "inputs": ["Katoomba", "southeast", "3 km"]},
|
16 |
+
{"id": 2, "function": "Between", "inputs": [1, "Echo Point"]}
|
17 |
+
]
|
18 |
+
},
|
19 |
+
{
|
20 |
+
"index": 3,
|
21 |
+
"instruction": "Plan a hiking route starting at Scafell Pike and travel 8 km to the west, then continue proceeding another 9 km westward.",
|
22 |
+
"steps": [
|
23 |
+
{"id": 1, "function": "Relative", "inputs": ["Scafell Pike", "west", "8 km"]},
|
24 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "9 km"]}
|
25 |
+
]
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"index": 4,
|
29 |
+
"instruction": "Starting from the Colosseum in Rome, navigate 8 kilometers at a 25° azimuth to go towards the northeast, and then move a further 2 kilometers in the northeast direction. Determine if this is a suitable location for a new tourist station setup.",
|
30 |
+
"steps": [
|
31 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Colosseum, Rome", "25°", "8 km"]},
|
32 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "2 km"]}
|
33 |
+
]
|
34 |
+
},
|
35 |
+
{
|
36 |
+
"index": 5,
|
37 |
+
"instruction": "Set up a communications relay point 4 km in the direction of 36° from Jasper, Alberta and then find the midpoint between this point and Banff, Alberta.",
|
38 |
+
"steps": [
|
39 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Jasper, Alberta", "36°", "4 km"]},
|
40 |
+
{"id": 2, "function": "Between", "inputs": ["Banff, Alberta", 1]}
|
41 |
+
]
|
42 |
+
},
|
43 |
+
{
|
44 |
+
"index": 6,
|
45 |
+
"instruction": "Identify the midpoint between the Statue of Liberty and the Eiffel Tower. From this midpoint, proceed 8 kilometers due west to establish a new GPS tracking station.",
|
46 |
+
"steps": [
|
47 |
+
{"id": 1, "function": "Between", "inputs": ["Eiffel Tower", "Statue of Liberty"]},
|
48 |
+
{"id": 2, "function": "Relative", "inputs": [1, "west", "8 km"]}
|
49 |
+
]
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"index": 7,
|
53 |
+
"instruction": "Determine a strategic location for a new lookout post by first finding the midpoint between New Orleans, USA, and Veracruz, Mexico. Then, identify a spot 8 km southwest of this midpoint.",
|
54 |
+
"steps": [
|
55 |
+
{"id": 1, "function": "Between", "inputs": ["New Orleans, USA", "Veracruz, Mexico"]},
|
56 |
+
{"id": 2, "function": "Relative", "inputs": [1, "south west", "8 km"]}
|
57 |
+
]
|
58 |
+
},
|
59 |
+
{
|
60 |
+
"index": 8,
|
61 |
+
"instruction": "Plan a marine survey starting at Santorini, Greece: First, move 9 km south to begin the survey in a new area. Then, identify the midpoint between Santorini and this new location, and move 1 km south from it for further exploration. From the original midpoint, proceed 5 km at an azimuth of 150° towards a final survey site. Find the midpoint between this location and the previous exploration point for setting a central sampling station.",
|
62 |
+
"steps": [
|
63 |
+
{"id": 1, "function": "Relative", "inputs": ["Santorini, Greece", "south", "9 km"]},
|
64 |
+
{"id": 2, "function": "Between", "inputs": ["Santorini, Greece", 1]},
|
65 |
+
{"id": 3, "function": "Relative", "inputs": [1, "south", "1 km"]},
|
66 |
+
{"id": 4, "function": "Azimuth", "inputs": [2, "150°", "5 km"]},
|
67 |
+
{"id": 5, "function": "Between", "inputs": [3, 4]}
|
68 |
+
]
|
69 |
+
},
|
70 |
+
{
|
71 |
+
"index": 9,
|
72 |
+
"instruction": "Plan a central spot for a camping trip by first finding the midpoint between Mont Blanc and Matterhorn, then find the midpoint between this point and Chamonix to refine the camping location.",
|
73 |
+
"steps": [
|
74 |
+
{"id": 1, "function": "Between", "inputs": ["Mont Blanc", "Matterhorn"]},
|
75 |
+
{"id": 2, "function": "Between", "inputs": [1, "Chamonix"]}
|
76 |
+
]
|
77 |
+
},
|
78 |
+
{
|
79 |
+
"index": 10,
|
80 |
+
"instruction": "Begin your geocaching adventure at Central Park in New York City. Move southwest for 9 km. Then head east for another 7 km. Finally, go back for an additional 1 km to find the hidden cache location.",
|
81 |
+
"steps": [
|
82 |
+
{"id": 1, "function": "Azimuth", "inputs": ["Central Park, New York City", "south west", "9 km"]},
|
83 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "east", "7 km"]},
|
84 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "west", "1 km"]}
|
85 |
+
]
|
86 |
+
},
|
87 |
+
{
|
88 |
+
"index": 11,
|
89 |
+
"instruction": "Plan a meeting point by moving 3 kilometers east of Central Park and then find a midpoint between this new location and Central Park.",
|
90 |
+
"steps": [
|
91 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park, Manhattan, New York", "east", "3 km"]},
|
92 |
+
{"id": 2, "function": "Between", "inputs": [1, "Central Park, Manhattan, New York"]}
|
93 |
+
]
|
94 |
+
},
|
95 |
+
{
|
96 |
+
"index": 12,
|
97 |
+
"instruction": "Identify the location that is 9 km to the southeast of Paris city center to set up a monitoring station.",
|
98 |
+
"steps": [
|
99 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris", "southeast", "9 km"]}
|
100 |
+
]
|
101 |
+
},
|
102 |
+
{
|
103 |
+
"index": 13,
|
104 |
+
"instruction": "Design a network of emergency medical drone hubs across Luxembourg. Start at the city hospital in Esch-sur-Alzette. First, plan a drone station 4 km to the northeast to reach nearby suburbs. Then, from there, move 6 km at an azimuth angle of 45° to cover rural areas toward Bettembourg. Continue by traveling 3 km at an azimuth of 190° to extend reach into southern valleys. Finally, identify the midpoint between this last location and the starting hospital as a backup drone relay site.",
|
105 |
+
"steps": [
|
106 |
+
{"id": 1, "function": "Relative", "inputs": ["Esch-sur-Alzette, Luxembourg", "northeast", "4 km"]},
|
107 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "45°", "6 km"]},
|
108 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "190°", "3 km"]},
|
109 |
+
{"id": 4, "function": "Between", "inputs": [3, "Esch-sur-Alzette Hospital, Luxembourg"]}
|
110 |
+
]
|
111 |
+
}
|
112 |
+
,
|
113 |
+
{
|
114 |
+
"index": 14,
|
115 |
+
"instruction": "Plan a scenic hiking route starting from Banff, Alberta. First, travel northwest for 2 km to reach a noted viewpoint. From there, continue northeast for 4 km, potentially spotting wildlife along the way. Finally, identify a midpoint between Banff and your current location to set a resting spot or picnic area for optimal views and convenience.",
|
116 |
+
"steps": [
|
117 |
+
{"id": 1, "function": "Relative", "inputs": ["Banff", "northwest", "2 km"]},
|
118 |
+
{"id": 2, "function": "Relative", "inputs": [1, "northeast", "4 km"]},
|
119 |
+
{"id": 3, "function": "Between", "inputs": ["Banff", 2]}
|
120 |
+
]
|
121 |
+
},
|
122 |
+
{
|
123 |
+
"index": 15,
|
124 |
+
"instruction": "Start at Central Park in New York City. Move northeast for 2 km to reach the area near The Met Cloisters in Fort Tryon Park. From there, head in the direction of 333° for 7 km towards the intersection of Riverside Drive and W 165th St. Finally, navigate 9 km in the direction of 62° to reach a suitable spot near Yonkers Avenue in Yonkers for the meteorological station setup.",
|
125 |
+
"steps": [
|
126 |
+
{"id": 1, "function": "Relative", "inputs": ["Central Park", "northeast", "2 km"]},
|
127 |
+
{"id": 2, "function": "Azimuth", "inputs": [1, "333°", "7 km"]},
|
128 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "62°", "9 km"]}
|
129 |
+
]
|
130 |
+
},
|
131 |
+
{
|
132 |
+
"index": 16,
|
133 |
+
"instruction": "Start at the Hellisheiði Geothermal Power Plant in Iceland and identify the area 5 kilometers to the northwest to assess potential expansion sites for sustainable energy infrastructure.",
|
134 |
+
"steps": [
|
135 |
+
{"id": 1, "function": "Relative", "inputs": ["Hellisheiði Geothermal Power Plant, Iceland", "northwest", "5 km"]}
|
136 |
+
]
|
137 |
+
}
|
138 |
+
,
|
139 |
+
{
|
140 |
+
"index": 17,
|
141 |
+
"instruction": "Plan a geological survey in the Cape Town area. First, find a point 3 km southwest of Signal Hill. Then, find the midpoint between this new location and Signal Hill. Next, calculate the midpoint between this result and Cape Town. Finally, determine the central point between all computed midpoints to establish a base camp for your survey operations.",
|
142 |
+
"steps": [
|
143 |
+
{"id": 1, "function": "Relative", "inputs": ["Signal Hill", "southwest", "3 km"]},
|
144 |
+
{"id": 2, "function": "Between", "inputs": [1, "Signal Hill"]},
|
145 |
+
{"id": 3, "function": "Between", "inputs": ["Cape Town", 1]},
|
146 |
+
{"id": 4, "function": "Between", "inputs": [2, 3]}
|
147 |
+
]
|
148 |
+
},
|
149 |
+
{
|
150 |
+
"index": 18,
|
151 |
+
"instruction": "Start at Praça do Comércio in Lisbon. First, calculate a point 1 km north from this location. Then, find the midpoint between this new location and Praça do Comércio. Finally, determine the midpoint between Praça do Comércio and the previously calculated midpoint to navigate effectively around the city.",
|
152 |
+
"steps": [
|
153 |
+
{"id": 1, "function": "Relative", "inputs": ["Praça do Comércio, Lisbon", "north", "1 km"]},
|
154 |
+
{"id": 2, "function": "Between", "inputs": [1, "Praça do Comércio, Lisbon"]},
|
155 |
+
{"id": 3, "function": "Between", "inputs": ["Praça do Comércio, Lisbon", 2]}
|
156 |
+
]
|
157 |
+
},
|
158 |
+
{
|
159 |
+
"index": 19,
|
160 |
+
"instruction": "Starting at the South Pole, travel 4 kilometers at an angle of 65° to find Point A. Determine the midpoint between the South Pole and Point A. From this midpoint, travel 7 kilometers at an angle of 184° to reach McMurdo Station.",
|
161 |
+
"steps": [
|
162 |
+
{"id": 1, "function": "Azimuth", "inputs": ["South Pole", "65°", "4 km"]},
|
163 |
+
{"id": 2, "function": "Between", "inputs": ["South Pole", 1]},
|
164 |
+
{"id": 3, "function": "Azimuth", "inputs": [2, "184°", "7 km"]}
|
165 |
+
]
|
166 |
+
},
|
167 |
+
{
|
168 |
+
"index": 20,
|
169 |
+
"instruction": "Identify a new exploration point 10 km northwest of the base camp at Yosemite National Park.",
|
170 |
+
"steps": [
|
171 |
+
{"id": 1, "function": "Relative", "inputs": ["Yosemite National Park", "northwest", "10 km"]}
|
172 |
+
]
|
173 |
+
}
|
174 |
+
]
|
dataset/dataset_initial.json
ADDED
@@ -0,0 +1,186 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"instruction": "3km east of Melbourne and 5km north of St Kilda.",
|
4 |
+
"steps": [
|
5 |
+
{"id": 1, "function": "Relative", "inputs": ["Melbourne", "east", "3 km"]},
|
6 |
+
{"id": 2, "function": "Relative", "inputs": ["St Kilda", "north", "5 km"]},
|
7 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
8 |
+
]
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"instruction": "7km north of Los Angeles, 4km west of Pasadena, then 3km northeast from their midpoint.",
|
12 |
+
"steps": [
|
13 |
+
{"id": 1, "function": "Relative", "inputs": ["Los Angeles", "north", "7 km"]},
|
14 |
+
{"id": 2, "function": "Relative", "inputs": ["Pasadena", "west", "4 km"]},
|
15 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
16 |
+
{"id": 4, "function": "Relative", "inputs": [3, "northeast", "3 km"]}
|
17 |
+
]
|
18 |
+
},
|
19 |
+
{
|
20 |
+
"instruction": "5km west of Sydney.",
|
21 |
+
"steps": [
|
22 |
+
{"id": 1, "function": "Relative", "inputs": ["Sydney", "west", "5 km"]}
|
23 |
+
]
|
24 |
+
},
|
25 |
+
{
|
26 |
+
"instruction": "2km south of Brisbane and 6km east of its result.",
|
27 |
+
"steps": [
|
28 |
+
{"id": 1, "function": "Relative", "inputs": ["Brisbane", "south", "2 km"]},
|
29 |
+
{"id": 2, "function": "Relative", "inputs": [1, "east", "6 km"]}
|
30 |
+
]
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"instruction": "5km northeast of Paris and 3km south of Versailles, then 4km northwest of their midpoint.",
|
34 |
+
"steps": [
|
35 |
+
{"id": 1, "function": "Relative", "inputs": ["Paris", "northeast", "5 km"]},
|
36 |
+
{"id": 2, "function": "Relative", "inputs": ["Versailles", "south", "3 km"]},
|
37 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
38 |
+
{"id": 4, "function": "Relative", "inputs": [3, "northwest", "4 km"]}
|
39 |
+
]
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"instruction": "8km southeast of Chicago, 10km west of Gary, then 6km north of their midpoint.",
|
43 |
+
"steps": [
|
44 |
+
{"id": 1, "function": "Relative", "inputs": ["Chicago", "southeast", "8 km"]},
|
45 |
+
{"id": 2, "function": "Relative", "inputs": ["Gary", "west", "10 km"]},
|
46 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
47 |
+
{"id": 4, "function": "Relative", "inputs": [3, "north", "6 km"]}
|
48 |
+
]
|
49 |
+
},
|
50 |
+
{
|
51 |
+
"instruction": "4km south of Madrid and 5km north of Getafe.",
|
52 |
+
"steps": [
|
53 |
+
{"id": 1, "function": "Relative", "inputs": ["Madrid", "south", "4 km"]},
|
54 |
+
{"id": 2, "function": "Relative", "inputs": ["Getafe", "north", "5 km"]},
|
55 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]}
|
56 |
+
]
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"instruction": "6km west of Rome and 3km south of Vatican City, then 2km southeast of their midpoint.",
|
60 |
+
"steps": [
|
61 |
+
{"id": 1, "function": "Relative", "inputs": ["Rome", "west", "6 km"]},
|
62 |
+
{"id": 2, "function": "Relative", "inputs": ["Vatican City", "south", "3 km"]},
|
63 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
64 |
+
{"id": 4, "function": "Relative", "inputs": [3, "southeast", "2 km"]}
|
65 |
+
]
|
66 |
+
},
|
67 |
+
{
|
68 |
+
"instruction": "5km north of Toronto and 3km east of its result.",
|
69 |
+
"steps": [
|
70 |
+
{"id": 1, "function": "Relative", "inputs": ["Toronto", "north", "5 km"]},
|
71 |
+
{"id": 2, "function": "Relative", "inputs": [1, "east", "3 km"]}
|
72 |
+
]
|
73 |
+
},
|
74 |
+
{
|
75 |
+
"instruction": "4km west of Osaka and 6km southwest of Kyoto, then 3km north of their midpoint.",
|
76 |
+
"steps": [
|
77 |
+
{"id": 1, "function": "Relative", "inputs": ["Osaka", "west", "4 km"]},
|
78 |
+
{"id": 2, "function": "Relative", "inputs": ["Kyoto", "southwest", "6 km"]},
|
79 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
80 |
+
{"id": 4, "function": "Relative", "inputs": [3, "north", "3 km"]}
|
81 |
+
]
|
82 |
+
},
|
83 |
+
{
|
84 |
+
"instruction": "6km west of Berlin, 4km north of Potsdam, then 5km southeast of their midpoint, finally 3km east.",
|
85 |
+
"steps": [
|
86 |
+
{"id": 1, "function": "Relative", "inputs": ["Berlin", "west", "6 km"]},
|
87 |
+
{"id": 2, "function": "Relative", "inputs": ["Potsdam", "north", "4 km"]},
|
88 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
89 |
+
{"id": 4, "function": "Relative", "inputs": [3, "southeast", "5 km"]},
|
90 |
+
{"id": 5, "function": "Relative", "inputs": [4, "east", "3 km"]}
|
91 |
+
]
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"instruction": "8km south of San Francisco, 6km west of Oakland, then 5km northeast, followed by 4km southeast.",
|
95 |
+
"steps": [
|
96 |
+
{"id": 1, "function": "Relative", "inputs": ["San Francisco", "south", "8 km"]},
|
97 |
+
{"id": 2, "function": "Relative", "inputs": ["Oakland", "west", "6 km"]},
|
98 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
99 |
+
{"id": 4, "function": "Relative", "inputs": [3, "northeast", "5 km"]},
|
100 |
+
{"id": 5, "function": "Relative", "inputs": [4, "southeast", "4 km"]}
|
101 |
+
]
|
102 |
+
},
|
103 |
+
{
|
104 |
+
"instruction": "5km northeast of Tokyo, 3km west of Chiba, then 7km south, followed by 6km northwest.",
|
105 |
+
"steps": [
|
106 |
+
{"id": 1, "function": "Relative", "inputs": ["Tokyo", "northeast", "5 km"]},
|
107 |
+
{"id": 2, "function": "Relative", "inputs": ["Chiba", "west", "3 km"]},
|
108 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
109 |
+
{"id": 4, "function": "Relative", "inputs": [3, "south", "7 km"]},
|
110 |
+
{"id": 5, "function": "Relative", "inputs": [4, "northwest", "6 km"]}
|
111 |
+
]
|
112 |
+
},
|
113 |
+
{
|
114 |
+
"instruction": "7km southeast of London, 5km north of Croydon, then 6km west, followed by 3km northeast.",
|
115 |
+
"steps": [
|
116 |
+
{"id": 1, "function": "Relative", "inputs": ["London", "southeast", "7 km"]},
|
117 |
+
{"id": 2, "function": "Relative", "inputs": ["Croydon", "north", "5 km"]},
|
118 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
119 |
+
{"id": 4, "function": "Relative", "inputs": [3, "west", "6 km"]},
|
120 |
+
{"id": 5, "function": "Relative", "inputs": [4, "northeast", "3 km"]}
|
121 |
+
]
|
122 |
+
},
|
123 |
+
{
|
124 |
+
"instruction": "10km south of New York, 4km west of Jersey City, then 8km east, followed by 5km north.",
|
125 |
+
"steps": [
|
126 |
+
{"id": 1, "function": "Relative", "inputs": ["New York", "south", "10 km"]},
|
127 |
+
{"id": 2, "function": "Relative", "inputs": ["Jersey City", "west", "4 km"]},
|
128 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
129 |
+
{"id": 4, "function": "Relative", "inputs": [3, "east", "8 km"]},
|
130 |
+
{"id": 5, "function": "Relative", "inputs": [4, "north", "5 km"]}
|
131 |
+
]
|
132 |
+
},
|
133 |
+
{
|
134 |
+
"instruction": "6km southwest of Melbourne, 4km north of Geelong, then 5km east, followed by 6km southeast.",
|
135 |
+
"steps": [
|
136 |
+
{"id": 1, "function": "Relative", "inputs": ["Melbourne", "southwest", "6 km"]},
|
137 |
+
{"id": 2, "function": "Relative", "inputs": ["Geelong", "north", "4 km"]},
|
138 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
139 |
+
{"id": 4, "function": "Relative", "inputs": [3, "east", "5 km"]},
|
140 |
+
{"id": 5, "function": "Relative", "inputs": [4, "southeast", "6 km"]}
|
141 |
+
]
|
142 |
+
},
|
143 |
+
{
|
144 |
+
"instruction": "7km west of Madrid, 5km north of Toledo, then 8km southeast, followed by 4km east, then 3km north.",
|
145 |
+
"steps": [
|
146 |
+
{"id": 1, "function": "Relative", "inputs": ["Madrid", "west", "7 km"]},
|
147 |
+
{"id": 2, "function": "Relative", "inputs": ["Toledo", "north", "5 km"]},
|
148 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
149 |
+
{"id": 4, "function": "Relative", "inputs": [3, "southeast", "8 km"]},
|
150 |
+
{"id": 5, "function": "Relative", "inputs": [4, "east", "4 km"]},
|
151 |
+
{"id": 6, "function": "Relative", "inputs": [5, "north", "3 km"]}
|
152 |
+
]
|
153 |
+
},
|
154 |
+
{
|
155 |
+
"instruction": "5km east of Rome, 3km south of Naples, then 6km northwest, followed by 4km southwest, then 3km north.",
|
156 |
+
"steps": [
|
157 |
+
{"id": 1, "function": "Relative", "inputs": ["Rome", "east", "5 km"]},
|
158 |
+
{"id": 2, "function": "Relative", "inputs": ["Naples", "south", "3 km"]},
|
159 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
160 |
+
{"id": 4, "function": "Relative", "inputs": [3, "northwest", "6 km"]},
|
161 |
+
{"id": 5, "function": "Relative", "inputs": [4, "southwest", "4 km"]},
|
162 |
+
{"id": 6, "function": "Relative", "inputs": [5, "north", "3 km"]}
|
163 |
+
]
|
164 |
+
},
|
165 |
+
{
|
166 |
+
"instruction": "8km north of Toronto, 5km west of Mississauga, then 4km southeast, followed by 6km south.",
|
167 |
+
"steps": [
|
168 |
+
{"id": 1, "function": "Relative", "inputs": ["Toronto", "north", "8 km"]},
|
169 |
+
{"id": 2, "function": "Relative", "inputs": ["Mississauga", "west", "5 km"]},
|
170 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
171 |
+
{"id": 4, "function": "Relative", "inputs": [3, "southeast", "4 km"]},
|
172 |
+
{"id": 5, "function": "Relative", "inputs": [4, "south", "6 km"]}
|
173 |
+
]
|
174 |
+
},
|
175 |
+
{
|
176 |
+
"instruction": "7km southwest of Osaka, 4km north of Kyoto, then 6km east, followed by 5km northeast, then 3km west.",
|
177 |
+
"steps": [
|
178 |
+
{"id": 1, "function": "Relative", "inputs": ["Osaka", "southwest", "7 km"]},
|
179 |
+
{"id": 2, "function": "Relative", "inputs": ["Kyoto", "north", "4 km"]},
|
180 |
+
{"id": 3, "function": "Between", "inputs": [1, 2]},
|
181 |
+
{"id": 4, "function": "Relative", "inputs": [3, "east", "6 km"]},
|
182 |
+
{"id": 5, "function": "Relative", "inputs": [4, "northeast", "5 km"]},
|
183 |
+
{"id": 6, "function": "Relative", "inputs": [5, "west", "3 km"]}
|
184 |
+
]
|
185 |
+
}
|
186 |
+
]
|
dataset/test.json
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"index": 1,
|
4 |
+
"instruction": "Plan a trip that involves determining the midpoint between Paris and London, and then finding another midpoint between this location and Paris to identify potential stopovers during travel.",
|
5 |
+
"steps": [
|
6 |
+
{"id": 1, "function": "Between", "inputs": ["Paris, France", "London, England"]},
|
7 |
+
{"id": 2, "function": "Between", "inputs": [1, "Paris, France"]}
|
8 |
+
]
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"index": 2,
|
12 |
+
"instruction": "Imagine you are planning a picnic hike in the Blue Mountains of Australia. Start your hike in Katoomba, move southeast for 3 kilometers, and then find a scenic midpoint between your new location and Echo Point to set up your picnic.",
|
13 |
+
"steps": [
|
14 |
+
{"id": 1, "function": "Relative", "inputs": ["Katoomba", "southeast", "3 km"]},
|
15 |
+
{"id": 2, "function": "Between", "inputs": [1, "Echo Point"]}
|
16 |
+
]
|
17 |
+
}
|
18 |
+
]
|
db/__pycache__/poly_db_util.cpython-310.pyc
ADDED
Binary file (3.09 kB). View file
|
|
db/__pycache__/poly_db_util.cpython-39.pyc
ADDED
Binary file (3.1 kB). View file
|
|
db/poly_db_util.py
ADDED
@@ -0,0 +1,134 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
"""
|
4 |
+
Created on Thu Sep 22 14:38:28 2022
|
5 |
+
|
6 |
+
@author: syed
|
7 |
+
"""
|
8 |
+
|
9 |
+
import mysql.connector as sql_db
|
10 |
+
import json
|
11 |
+
#import mysql.connector
|
12 |
+
|
13 |
+
# Initialize connection.
|
14 |
+
# Uses st.experimental_singleton to only run once.
|
15 |
+
#@st.experimental_singleton
|
16 |
+
def init_connection():
|
17 |
+
#return sql_db.connect(**st.secrets["mysql"])
|
18 |
+
# return sql_db.connect(user='root', password='root1234',
|
19 |
+
# host='127.0.0.1',port=3306,
|
20 |
+
# database='rsi_polygon_schema')
|
21 |
+
return sql_db.connect(user='freedb_root_mehtab', password='b%9bYQ%5TsK%mAD',
|
22 |
+
host='sql.freedb.tech',port=3306,
|
23 |
+
database='freedb_rsi_polygon_schema')
|
24 |
+
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
|
29 |
+
|
30 |
+
query_insert_rating = "insert into rating(shape_id,expert_id, ratings) values(%s,%s,%s)"
|
31 |
+
|
32 |
+
#query_update_rating = "update rating set ratings = %s where shape_id = %s and expert_id = %s"
|
33 |
+
|
34 |
+
|
35 |
+
query_insert_shape = "insert into shape(ase,level_1, level_2, level_3, geojson) values(%s,%s,%s,%s,%s)"
|
36 |
+
|
37 |
+
query_insert_expert = "insert into expert(name,expertise, tools_expert) values(%s,%s,%s)"
|
38 |
+
|
39 |
+
|
40 |
+
def update_rating_query(shape_id, expert_id, ratings):
|
41 |
+
query_rating = "update rating set ratings = '"+str(ratings)+"' where"
|
42 |
+
query_rating += " shape_id = '"+str(shape_id)+"' and expert_id = '"+str(expert_id)+"'"
|
43 |
+
return query_rating
|
44 |
+
|
45 |
+
|
46 |
+
def get_rating_query(shape_id, expert_id):
|
47 |
+
query_rating = "select * from rating where "
|
48 |
+
if shape_id is not None:
|
49 |
+
query_rating += "shape_id = '"+str(shape_id)+"' "
|
50 |
+
if expert_id is not None:
|
51 |
+
query_rating += "and expert_id = '"+str(expert_id)+"' "
|
52 |
+
|
53 |
+
return query_rating
|
54 |
+
|
55 |
+
def get_shape_query(ase, level_1, level_2, level_3):
|
56 |
+
query_shape = "select * from shape where "
|
57 |
+
if ase is not None:
|
58 |
+
query_shape += "ase = '"+ase+"' "
|
59 |
+
if level_1 is not None:
|
60 |
+
query_shape += "and level_1 = '"+level_1+"' "
|
61 |
+
if level_2 is not None:
|
62 |
+
query_shape += "and level_2 = '"+level_2+"' "
|
63 |
+
if level_3 is not None:
|
64 |
+
query_shape += "and level_3 = '"+level_3+"'"
|
65 |
+
return query_shape
|
66 |
+
|
67 |
+
def get_expert_query(name, expertise):
|
68 |
+
query_expert = "select * from expert where "
|
69 |
+
if name is not None:
|
70 |
+
query_expert += "name = '"+name+"' "
|
71 |
+
if expertise is not None:
|
72 |
+
query_expert += "and expertise = '"+expertise+"' "
|
73 |
+
return query_expert
|
74 |
+
|
75 |
+
def apply_rating(name, expertise, tools_selected,
|
76 |
+
rating_selected, ase, level_1, level_2, level_3, geojson):
|
77 |
+
connection = init_connection()
|
78 |
+
cursor = connection.cursor(prepared=True)
|
79 |
+
|
80 |
+
query_shape = get_shape_query(ase, level_1, level_2, level_3)
|
81 |
+
|
82 |
+
#tuple_shape = (ase, level_1, level_2, level_3)
|
83 |
+
tuple_expert = (name, expertise, str(tools_selected)[1:-1])
|
84 |
+
cursor.execute(query_shape)
|
85 |
+
record_shape = cursor.fetchone()
|
86 |
+
print("Record Shape:", record_shape)
|
87 |
+
print("Shape Select Query:", cursor.statement)
|
88 |
+
if record_shape is None:
|
89 |
+
tuple_insert_shape = (ase, level_1, level_2, level_3, json.dumps(geojson))
|
90 |
+
print(len(geojson))
|
91 |
+
cursor.execute(query_insert_shape, tuple_insert_shape)
|
92 |
+
connection.commit()
|
93 |
+
shape_id = cursor.lastrowid
|
94 |
+
print(f"Insert query executed with id : {shape_id}")
|
95 |
+
else:
|
96 |
+
shape_id = record_shape[0]
|
97 |
+
|
98 |
+
query_expert = get_expert_query(name, expertise)
|
99 |
+
|
100 |
+
cursor.execute(query_expert)
|
101 |
+
record_expert = cursor.fetchone()
|
102 |
+
print("Expert Select Query:", cursor.statement)
|
103 |
+
if record_expert is None:
|
104 |
+
cursor.execute(query_insert_expert, tuple_expert)
|
105 |
+
connection.commit()
|
106 |
+
expert_id = cursor.lastrowid
|
107 |
+
else:
|
108 |
+
expert_id = record_expert[0]
|
109 |
+
|
110 |
+
query_rating = get_rating_query(shape_id, expert_id)
|
111 |
+
cursor.execute(query_rating)
|
112 |
+
record_rating = cursor.fetchone()
|
113 |
+
|
114 |
+
print("Ratings Select Query:", cursor.statement)
|
115 |
+
|
116 |
+
|
117 |
+
print("Shape ID", shape_id, "...Expert ID", expert_id)
|
118 |
+
tuple_rating = (shape_id, expert_id, rating_selected)
|
119 |
+
if record_rating is None:
|
120 |
+
cursor.execute(query_insert_rating, tuple_rating)
|
121 |
+
connection.commit()
|
122 |
+
else:
|
123 |
+
cursor.execute(update_rating_query(shape_id, expert_id, rating_selected))
|
124 |
+
connection.commit()
|
125 |
+
|
126 |
+
|
127 |
+
|
128 |
+
|
129 |
+
|
130 |
+
|
131 |
+
|
132 |
+
|
133 |
+
|
134 |
+
|
dependencies.txt
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Bottleneck==1.4.2
|
2 |
+
└── numpy [required: Any, installed: 1.26.4]
|
3 |
+
Brotli==1.0.9
|
4 |
+
cffi==1.17.1
|
5 |
+
└── pycparser [required: Any, installed: 2.22]
|
6 |
+
colorama==0.4.6
|
7 |
+
folium==0.19.2
|
8 |
+
├── branca [required: >=0.6.0, installed: 0.8.1]
|
9 |
+
│ └── Jinja2 [required: >=3, installed: 3.1.5]
|
10 |
+
│ └── MarkupSafe [required: >=2.0, installed: 3.0.2]
|
11 |
+
├── Jinja2 [required: >=2.9, installed: 3.1.5]
|
12 |
+
│ └── MarkupSafe [required: >=2.0, installed: 3.0.2]
|
13 |
+
├── numpy [required: Any, installed: 1.26.4]
|
14 |
+
├── requests [required: Any, installed: 2.32.3]
|
15 |
+
│ ├── certifi [required: >=2017.4.17, installed: 2024.12.14]
|
16 |
+
│ ├── charset-normalizer [required: >=2,<4, installed: 3.4.1]
|
17 |
+
│ ├── idna [required: >=2.5,<4, installed: 3.10]
|
18 |
+
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.3.0]
|
19 |
+
└── xyzservices [required: Any, installed: 2024.9.0]
|
20 |
+
GDAL==3.6.2
|
21 |
+
gensim==4.3.3
|
22 |
+
├── numpy [required: >=1.18.5,<2.0, installed: 1.26.4]
|
23 |
+
├── scipy [required: >=1.7.0,<1.14.0, installed: 1.13.1]
|
24 |
+
│ └── numpy [required: >=1.22.4,<2.3, installed: 1.26.4]
|
25 |
+
└── smart-open [required: >=1.8.1, installed: 7.1.0]
|
26 |
+
└── wrapt [required: Any, installed: 1.17.0]
|
27 |
+
geopandas==0.11.1
|
28 |
+
├── fiona [required: >=1.8, installed: 1.10.1]
|
29 |
+
│ ├── attrs [required: >=19.2.0, installed: 24.3.0]
|
30 |
+
│ ├── certifi [required: Any, installed: 2024.12.14]
|
31 |
+
│ ├── click [required: ~=8.0, installed: 8.1.8]
|
32 |
+
│ ├── click-plugins [required: >=1.0, installed: 1.1.1]
|
33 |
+
│ │ └── click [required: >=4.0, installed: 8.1.8]
|
34 |
+
│ └── cligj [required: >=0.5, installed: 0.7.2]
|
35 |
+
│ └── click [required: >=4.0, installed: 8.1.8]
|
36 |
+
├── packaging [required: Any, installed: 24.2]
|
37 |
+
├── pandas [required: >=1.0.0, installed: 2.2.3]
|
38 |
+
│ ├── numpy [required: >=1.22.4, installed: 1.26.4]
|
39 |
+
│ ├── python-dateutil [required: >=2.8.2, installed: 2.9.0.post0]
|
40 |
+
│ │ └── six [required: >=1.5, installed: 1.17.0]
|
41 |
+
│ ├── pytz [required: >=2020.1, installed: 2024.2]
|
42 |
+
│ └── tzdata [required: >=2022.7, installed: 2024.2]
|
43 |
+
├── pyproj [required: >=2.6.1.post1, installed: 3.6.1]
|
44 |
+
│ └── certifi [required: Any, installed: 2024.12.14]
|
45 |
+
└── Shapely [required: >=1.7,<2, installed: 1.8.4]
|
46 |
+
h2==4.1.0
|
47 |
+
├── hpack [required: >=4.0,<5, installed: 4.0.0]
|
48 |
+
└── hyperframe [required: >=6.0,<7, installed: 6.0.1]
|
49 |
+
mapclassify==2.8.1
|
50 |
+
├── networkx [required: >=2.7, installed: 3.4.2]
|
51 |
+
├── numpy [required: >=1.23, installed: 1.26.4]
|
52 |
+
├── pandas [required: >=1.4,!=1.5.0, installed: 2.2.3]
|
53 |
+
│ ├── numpy [required: >=1.22.4, installed: 1.26.4]
|
54 |
+
│ ├── python-dateutil [required: >=2.8.2, installed: 2.9.0.post0]
|
55 |
+
│ │ └── six [required: >=1.5, installed: 1.17.0]
|
56 |
+
│ ├── pytz [required: >=2020.1, installed: 2024.2]
|
57 |
+
│ └── tzdata [required: >=2022.7, installed: 2024.2]
|
58 |
+
├── scikit-learn [required: >=1.0, installed: 1.5.2]
|
59 |
+
│ ├── joblib [required: >=1.2.0, installed: 1.4.2]
|
60 |
+
│ ├── numpy [required: >=1.19.5, installed: 1.26.4]
|
61 |
+
│ ├── scipy [required: >=1.6.0, installed: 1.13.1]
|
62 |
+
│ │ └── numpy [required: >=1.22.4,<2.3, installed: 1.26.4]
|
63 |
+
│ └── threadpoolctl [required: >=3.1.0, installed: 3.5.0]
|
64 |
+
└── scipy [required: >=1.8, installed: 1.13.1]
|
65 |
+
└── numpy [required: >=1.22.4,<2.3, installed: 1.26.4]
|
66 |
+
matplotlib==3.9.2
|
67 |
+
├── contourpy [required: >=1.0.1, installed: 1.3.1]
|
68 |
+
│ └── numpy [required: >=1.23, installed: 1.26.4]
|
69 |
+
├── cycler [required: >=0.10, installed: 0.12.1]
|
70 |
+
├── fonttools [required: >=4.22.0, installed: 4.55.3]
|
71 |
+
├── kiwisolver [required: >=1.3.1, installed: 1.4.4]
|
72 |
+
├── numpy [required: >=1.23, installed: 1.26.4]
|
73 |
+
├── packaging [required: >=20.0, installed: 24.2]
|
74 |
+
├── pillow [required: >=8, installed: 11.0.0]
|
75 |
+
├── pyparsing [required: >=2.3.1, installed: 3.2.0]
|
76 |
+
└── python-dateutil [required: >=2.7, installed: 2.9.0.post0]
|
77 |
+
└── six [required: >=1.5, installed: 1.17.0]
|
78 |
+
munkres==1.1.4
|
79 |
+
numexpr==2.10.1
|
80 |
+
└── numpy [required: >=1.23.0, installed: 1.26.4]
|
81 |
+
pipdeptree==2.24.0
|
82 |
+
├── packaging [required: >=24.1, installed: 24.2]
|
83 |
+
└── pip [required: >=24.2, installed: 24.3.1]
|
84 |
+
PySocks==1.7.1
|
85 |
+
Rtree==1.0.1
|
86 |
+
setuptools==75.1.0
|
87 |
+
tokenizers==0.21.0
|
88 |
+
└── huggingface-hub [required: >=0.16.4,<1.0, installed: 0.27.0]
|
89 |
+
├── filelock [required: Any, installed: 3.16.1]
|
90 |
+
├── fsspec [required: >=2023.5.0, installed: 2024.12.0]
|
91 |
+
├── packaging [required: >=20.9, installed: 24.2]
|
92 |
+
├── PyYAML [required: >=5.1, installed: 6.0.2]
|
93 |
+
├── requests [required: Any, installed: 2.32.3]
|
94 |
+
│ ├── certifi [required: >=2017.4.17, installed: 2024.12.14]
|
95 |
+
│ ├── charset-normalizer [required: >=2,<4, installed: 3.4.1]
|
96 |
+
│ ├── idna [required: >=2.5,<4, installed: 3.10]
|
97 |
+
│ └── urllib3 [required: >=1.21.1,<3, installed: 2.3.0]
|
98 |
+
├── tqdm [required: >=4.42.1, installed: 4.67.1]
|
99 |
+
└── typing_extensions [required: >=3.7.4.3, installed: 4.12.2]
|
100 |
+
unicodedata2==15.1.0
|
101 |
+
wheel==0.44.0
|
102 |
+
zstandard==0.23.0
|
disambiguation/__pycache__/disambiguate.cpython-310.pyc
ADDED
Binary file (3.25 kB). View file
|
|
disambiguation/__pycache__/disambiguate.cpython-39.pyc
ADDED
Binary file (2.2 kB). View file
|
|
disambiguation/disambiguate.py
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
"""
|
4 |
+
Created on Mon Aug 1 13:11:36 2022
|
5 |
+
|
6 |
+
@author: syed
|
7 |
+
"""
|
8 |
+
import requests
|
9 |
+
import urllib3
|
10 |
+
import json
|
11 |
+
from geocoder import geo_level1
|
12 |
+
from geocoder import geo_level2
|
13 |
+
from geocoder import geo_level3
|
14 |
+
|
15 |
+
from utils import geoutil
|
16 |
+
import re
|
17 |
+
import regex_spatial
|
18 |
+
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
19 |
+
|
20 |
+
|
21 |
+
|
22 |
+
|
23 |
+
def dismabiguate_entities(doc, ent, ase, level_1, level_2, level_3, midmid):
|
24 |
+
return get_coordinates(ent, ase, level_1, level_2, level_3, midmid)
|
25 |
+
def get_coordinates(ent, ase, level_1, level_2, level_3, midmid):
|
26 |
+
request_url = 'https://nominatim.openstreetmap.org/search.php?q='+ase+'&polygon_geojson=1&accept-language=en&format=jsonv2'
|
27 |
+
headers = {
|
28 |
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15"
|
29 |
+
}
|
30 |
+
page = requests.get(request_url, headers=headers, verify=False)
|
31 |
+
# page = requests.get(request_url, verify=False)
|
32 |
+
# print(request_url, '++++++')
|
33 |
+
# print(ent, '++++++')
|
34 |
+
# print(ase, '++++++')
|
35 |
+
# print(level_1, '++++++')
|
36 |
+
# print(level_2, '++++++')
|
37 |
+
# print(level_3, '++++++')
|
38 |
+
# print(midmid, '++++++')
|
39 |
+
|
40 |
+
|
41 |
+
json_content = json.loads(page.content)
|
42 |
+
# json_content = json.loads(aa)
|
43 |
+
print(json_content, 'jjjjj')
|
44 |
+
all_coordinates = json_content[0]['geojson']['coordinates'][0]
|
45 |
+
centroid = (float(json_content[0]['lon']), float(json_content[0]['lat']))
|
46 |
+
for p in all_coordinates:
|
47 |
+
p2 = (p[0], p[1])
|
48 |
+
angle = geoutil.calculate_bearing(centroid, p2)
|
49 |
+
p.append(angle)
|
50 |
+
mid1 = None
|
51 |
+
mid2 = None
|
52 |
+
coordinates = all_coordinates
|
53 |
+
# if level_1 is not None:
|
54 |
+
#
|
55 |
+
# all_coordinates, centroid, mid1, mid2 = geo_level1.get_level1_coordinates(all_coordinates, centroid, level_1, midmid)
|
56 |
+
|
57 |
+
# if level_2 is not None:
|
58 |
+
# if level_1 is not None and level_1.lower() not in geo_level1.center:
|
59 |
+
# all_coordinates, centroid = geo_level2.get_level2_coordinates(coordinates, centroid, level_2, level_1)
|
60 |
+
# else:
|
61 |
+
# print ("Else executed")
|
62 |
+
# all_coordinates, centroid = geo_level2.get_level2_coordinates(all_coordinates, centroid, level_2, level_1)
|
63 |
+
|
64 |
+
if level_3 is not None:
|
65 |
+
all_coordinates, centroid = geo_level3.get_level3_coordinates(coordinates, centroid, level_3, level_1)
|
66 |
+
|
67 |
+
geojson = get_geojson(ent, all_coordinates, centroid)
|
68 |
+
|
69 |
+
return geojson
|
70 |
+
|
71 |
+
|
72 |
+
def dismabiguate_entities_between(doc, ent, ase, level_1, level_2, level_3, midmid):
|
73 |
+
return get_coordinates_between(doc, ent, ase, level_1, level_2, level_3, midmid)
|
74 |
+
|
75 |
+
|
76 |
+
def get_coordinates_between(doc, ent, ase, level_1, level_2, level_3, midmid):
|
77 |
+
|
78 |
+
# first ase
|
79 |
+
request_url = 'https://nominatim.openstreetmap.org/search.php?q=' + doc.ents[0].text + '&polygon_geojson=1&accept-language=en&format=jsonv2'
|
80 |
+
headers = {
|
81 |
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15"
|
82 |
+
}
|
83 |
+
page1 = requests.get(request_url, headers=headers, verify=False)
|
84 |
+
|
85 |
+
# second ase
|
86 |
+
request_url = 'https://nominatim.openstreetmap.org/search.php?q=' + doc.ents[1].text + '&polygon_geojson=1&accept-language=en&format=jsonv2'
|
87 |
+
headers = {
|
88 |
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15"
|
89 |
+
}
|
90 |
+
page = requests.get(request_url, headers=headers, verify=False)
|
91 |
+
|
92 |
+
|
93 |
+
request_url = 'https://nominatim.openstreetmap.org/search.php?q=' + ase + '&polygon_geojson=1&accept-language=en&format=jsonv2'
|
94 |
+
headers = {
|
95 |
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15"
|
96 |
+
}
|
97 |
+
page = requests.get(request_url, headers=headers, verify=False)
|
98 |
+
print('bebe')
|
99 |
+
print(ase)
|
100 |
+
print(doc.ents)
|
101 |
+
|
102 |
+
json_content = json.loads(page.content)
|
103 |
+
# json_content = json.loads(aa)
|
104 |
+
# print(json_content, 'jjj')
|
105 |
+
all_coordinates = json_content[0]['geojson']['coordinates'][0]
|
106 |
+
centroid = (float(json_content[0]['lon']), float(json_content[0]['lat']))
|
107 |
+
for p in all_coordinates:
|
108 |
+
p2 = (p[0], p[1])
|
109 |
+
angle = geoutil.calculate_bearing(centroid, p2)
|
110 |
+
p.append(angle)
|
111 |
+
mid1 = None
|
112 |
+
mid2 = None
|
113 |
+
coordinates = all_coordinates
|
114 |
+
if level_1 is not None:
|
115 |
+
|
116 |
+
all_coordinates, centroid, mid1, mid2 = geo_level1.get_level1_coordinates(all_coordinates, centroid, level_1, midmid)
|
117 |
+
|
118 |
+
if level_2 is not None:
|
119 |
+
if level_1 is not None and level_1.lower() not in geo_level1.center:
|
120 |
+
all_coordinates, centroid = geo_level2.get_level2_coordinates(coordinates, centroid, level_2, level_1)
|
121 |
+
else:
|
122 |
+
print ("Else executed")
|
123 |
+
all_coordinates, centroid = geo_level2.get_level2_coordinates(all_coordinates, centroid, level_2, level_1)
|
124 |
+
|
125 |
+
if level_3 is not None:
|
126 |
+
all_coordinates, centroid = geo_level3.get_level3_coordinates(coordinates, centroid, level_3, level_1)
|
127 |
+
|
128 |
+
geojson = get_geojson(ent, all_coordinates, centroid)
|
129 |
+
|
130 |
+
return geojson
|
131 |
+
|
132 |
+
def get_geojson(ent, arr, centroid):
|
133 |
+
poly_json = {}
|
134 |
+
poly_json['type'] = 'FeatureCollection'
|
135 |
+
poly_json['features'] = []
|
136 |
+
coordinates= []
|
137 |
+
coordinates.append(arr)
|
138 |
+
poly_json['features'].append({
|
139 |
+
'type':'Feature',
|
140 |
+
'id': ent,
|
141 |
+
'properties': {
|
142 |
+
'centroid': centroid
|
143 |
+
},
|
144 |
+
'geometry': {
|
145 |
+
'type':'Polygon',
|
146 |
+
'coordinates': coordinates
|
147 |
+
}
|
148 |
+
})
|
149 |
+
return poly_json
|
150 |
+
|
151 |
+
def export(ent, poly_json):
|
152 |
+
with open(ent+'.geojson', 'w') as outfile:
|
153 |
+
json.dump(poly_json, outfile)
|
154 |
+
|
155 |
+
|
docs/Notes.docx
ADDED
Binary file (15.6 kB). View file
|
|
docs/~$Notes.docx
ADDED
Binary file (162 Bytes). View file
|
|
geocoder/.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
geocoder/__pycache__/geo_level1.cpython-310.pyc
ADDED
Binary file (4.18 kB). View file
|
|
geocoder/__pycache__/geo_level1.cpython-39.pyc
ADDED
Binary file (3.95 kB). View file
|
|
geocoder/__pycache__/geo_level11.cpython-310.pyc
ADDED
Binary file (3.86 kB). View file
|
|
geocoder/__pycache__/geo_level2.cpython-310.pyc
ADDED
Binary file (2.84 kB). View file
|
|
geocoder/__pycache__/geo_level2.cpython-39.pyc
ADDED
Binary file (2.87 kB). View file
|
|
geocoder/__pycache__/geo_level3.cpython-310.pyc
ADDED
Binary file (3.61 kB). View file
|
|
geocoder/__pycache__/geo_level3.cpython-39.pyc
ADDED
Binary file (2.78 kB). View file
|
|
geocoder/geo_level1.py
ADDED
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
"""
|
4 |
+
Created on Tue Aug 2 12:38:31 2022
|
5 |
+
|
6 |
+
@author: syed
|
7 |
+
"""
|
8 |
+
import regex_spatial
|
9 |
+
from utils import geoutil
|
10 |
+
|
11 |
+
|
12 |
+
north = ["north", "N'", "North", "NORTH"]
|
13 |
+
south = ["south", "S'", "South", "SOUTH"]
|
14 |
+
east = ["east", "E'", "East", "EAST"]
|
15 |
+
west = ["west", "W'", "West", "WEST"]
|
16 |
+
northeast = ["north-east", "NE'", "north east", "NORTH-EAST", "North East", "NORTH EAST", 'northeast']
|
17 |
+
southeast = ["south-east", "SE'", "south east", "SOUTH-EAST", "South East", "SOUTH EAST", 'southeast']
|
18 |
+
northwest = ["north-west", "NW'", "north west", "NORTH-WEST", "North West", "NORTH WEST", 'northwest']
|
19 |
+
southwest = ["south-west", "SW'", "south west", "SOUTH-WEST", "South West", "SOUTH WEST", 'southwest']
|
20 |
+
center = ["center","central", "downtown","midtown"]
|
21 |
+
def get_min_max(direction):
|
22 |
+
regex = regex_spatial.get_directional_regex()
|
23 |
+
direction_list = regex.split("|")
|
24 |
+
if direction in direction_list:
|
25 |
+
if direction in east:
|
26 |
+
return (337, 22)
|
27 |
+
if direction in northeast:
|
28 |
+
return (22, 67)
|
29 |
+
if direction in north:
|
30 |
+
return (67, 112)
|
31 |
+
if direction in northwest:
|
32 |
+
return (112, 157)
|
33 |
+
if direction in west:
|
34 |
+
return (157, 202)
|
35 |
+
if direction in southwest:
|
36 |
+
return (202, 247)
|
37 |
+
if direction in south:
|
38 |
+
return (247, 292)
|
39 |
+
if direction in southeast:
|
40 |
+
return (292, 337)
|
41 |
+
|
42 |
+
return None
|
43 |
+
|
44 |
+
|
45 |
+
def get_min_max(direction):
|
46 |
+
regex = regex_spatial.get_directional_regex()
|
47 |
+
direction_list = regex.split("|")
|
48 |
+
if direction in direction_list:
|
49 |
+
if direction in east:
|
50 |
+
return (337, 22)
|
51 |
+
if direction in northeast:
|
52 |
+
return (292, 337)
|
53 |
+
if direction in north:
|
54 |
+
return (247, 292)
|
55 |
+
if direction in northwest:
|
56 |
+
return (202, 247)
|
57 |
+
if direction in west:
|
58 |
+
return (157, 202)
|
59 |
+
if direction in southwest:
|
60 |
+
return (112, 157)
|
61 |
+
if direction in south:
|
62 |
+
return (67, 112)
|
63 |
+
if direction in southeast:
|
64 |
+
return (22, 67)
|
65 |
+
|
66 |
+
return None
|
67 |
+
|
68 |
+
# def get_min_max(direction):
|
69 |
+
# regex = regex_spatial.get_directional_regex()
|
70 |
+
# direction_list = regex.split("|")
|
71 |
+
# if direction in direction_list:
|
72 |
+
# if direction in north:
|
73 |
+
# return (337, 22)
|
74 |
+
# if direction in northeast:
|
75 |
+
# return (22, 67)
|
76 |
+
# if direction in east:
|
77 |
+
# return (67, 112)
|
78 |
+
# if direction in southeast:
|
79 |
+
# return (112, 157)
|
80 |
+
# if direction in south:
|
81 |
+
# return (157, 202)
|
82 |
+
# if direction in southwest:
|
83 |
+
# return (202, 247)
|
84 |
+
# if direction in west:
|
85 |
+
# return (247, 292)
|
86 |
+
# if direction in northwest:
|
87 |
+
# return (292, 337)
|
88 |
+
#
|
89 |
+
# return None
|
90 |
+
|
91 |
+
def get_directional_coordinates_by_angle(coordinates, direction, minimum, maximum):
|
92 |
+
direction_coordinates = []
|
93 |
+
for p in coordinates:
|
94 |
+
if direction in east:
|
95 |
+
if p[2] >= minimum or p[2] <= maximum:
|
96 |
+
direction_coordinates.append(p)
|
97 |
+
|
98 |
+
else:
|
99 |
+
if p[2] >= minimum and p[2] <= maximum:
|
100 |
+
direction_coordinates.append(p)
|
101 |
+
return direction_coordinates
|
102 |
+
|
103 |
+
def get_directional_coordinates(coordinates, direction, centroid , minimum, maximum, is_midmid):
|
104 |
+
direction_coordinates = get_directional_coordinates_by_angle(coordinates, direction, minimum, maximum)
|
105 |
+
print(direction_coordinates, 'ddddd')
|
106 |
+
midmid1, midmid2= geoutil.get_midmid_point(centroid, direction_coordinates[0],direction_coordinates[-1], is_midmid)
|
107 |
+
if direction in west:
|
108 |
+
maxi = max(p[2] for p in direction_coordinates)
|
109 |
+
mini = min(p[2] for p in direction_coordinates)
|
110 |
+
index_mini = 0
|
111 |
+
index_maxi = 0
|
112 |
+
for idx,p in enumerate(direction_coordinates):
|
113 |
+
if p[2] == mini:
|
114 |
+
index_mini = idx
|
115 |
+
if p[2] == maxi:
|
116 |
+
index_maxi = idx
|
117 |
+
|
118 |
+
direction_coordinates.insert(index_maxi+1, midmid2)
|
119 |
+
direction_coordinates.insert(index_mini+1, midmid1)
|
120 |
+
print(index_maxi+1, midmid2, 'imim')
|
121 |
+
print(index_mini+1, midmid1, 'imim')
|
122 |
+
else:
|
123 |
+
direction_coordinates.append(midmid2)
|
124 |
+
direction_coordinates.append(midmid1)
|
125 |
+
|
126 |
+
return direction_coordinates, midmid1, midmid2
|
127 |
+
|
128 |
+
def get_level1_coordinates(coordinates, centroid, direction, is_midmid):
|
129 |
+
min_max = get_min_max(direction)
|
130 |
+
if min_max is not None:
|
131 |
+
coordinates, mid1, mid2 = get_directional_coordinates(coordinates, direction, centroid,
|
132 |
+
min_max[0], min_max[1],is_midmid)
|
133 |
+
# print(mid1, 'min_max')
|
134 |
+
# print(mid2, 'min_max')
|
135 |
+
print(coordinates, 'min_max')
|
136 |
+
print("Level 1 Coordinates///")
|
137 |
+
for idx, p in enumerate(coordinates):
|
138 |
+
print(idx, p)
|
139 |
+
return coordinates, centroid, mid1, mid2
|
140 |
+
elif direction.lower() in center:
|
141 |
+
return get_central(coordinates, centroid, direction, is_midmid), centroid, None, None
|
142 |
+
else :
|
143 |
+
return coordinates, centroid, None, None
|
144 |
+
|
145 |
+
|
146 |
+
def get_central(coordinates, centroid, direction, is_midmid):
|
147 |
+
|
148 |
+
n_min_max = get_min_max("north")
|
149 |
+
n_coordinates=get_directional_coordinates_by_angle(coordinates, "north", n_min_max[0], n_min_max[1])
|
150 |
+
n_mid1, n_mid2 = geoutil.get_midmid_point(centroid,n_coordinates[0],n_coordinates[-1], is_midmid)
|
151 |
+
|
152 |
+
ne_min_max = get_min_max("north east")
|
153 |
+
ne_coordinates=get_directional_coordinates_by_angle(coordinates, "north east", ne_min_max[0], ne_min_max[1])
|
154 |
+
ne_mid1, ne_mid2 = geoutil.get_midmid_point(centroid,ne_coordinates[0],ne_coordinates[-1], is_midmid)
|
155 |
+
|
156 |
+
e_min_max = get_min_max("east")
|
157 |
+
e_coordinates=get_directional_coordinates_by_angle(coordinates, "east", e_min_max[0], e_min_max[1])
|
158 |
+
e_mid1, e_mid2 = geoutil.get_midmid_point(centroid,e_coordinates[0],e_coordinates[-1], is_midmid)
|
159 |
+
|
160 |
+
se_min_max = get_min_max("south east")
|
161 |
+
se_coordinates=get_directional_coordinates_by_angle(coordinates, "south east", se_min_max[0], se_min_max[1])
|
162 |
+
se_mid1, se_mid2 = geoutil.get_midmid_point(centroid,se_coordinates[0],se_coordinates[-1], is_midmid)
|
163 |
+
|
164 |
+
s_min_max = get_min_max("south")
|
165 |
+
s_coordinates=get_directional_coordinates_by_angle(coordinates, "south", s_min_max[0], s_min_max[1])
|
166 |
+
s_mid1, s_mid2 = geoutil.get_midmid_point(centroid,s_coordinates[0],s_coordinates[-1], is_midmid)
|
167 |
+
|
168 |
+
sw_min_max = get_min_max("south west")
|
169 |
+
sw_coordinates=get_directional_coordinates_by_angle(coordinates, "south west", sw_min_max[0], sw_min_max[1])
|
170 |
+
sw_mid1, sw_mid2 = geoutil.get_midmid_point(centroid,sw_coordinates[0],sw_coordinates[-1], is_midmid)
|
171 |
+
|
172 |
+
w_min_max = get_min_max("west")
|
173 |
+
w_coordinates=get_directional_coordinates_by_angle(coordinates, "west", w_min_max[0], w_min_max[1])
|
174 |
+
w_mid1, w_mid2 = geoutil.get_midmid_point(centroid,w_coordinates[0],w_coordinates[-1], is_midmid)
|
175 |
+
|
176 |
+
nw_min_max = get_min_max("north west")
|
177 |
+
nw_coordinates=get_directional_coordinates_by_angle(coordinates, "north west", nw_min_max[0], nw_min_max[1])
|
178 |
+
nw_mid1, nw_mid2 = geoutil.get_midmid_point(centroid,nw_coordinates[0],nw_coordinates[-1], is_midmid)
|
179 |
+
|
180 |
+
central_coordindates =[e_mid1, e_mid2, ne_mid1, ne_mid2, n_mid1, n_mid2,
|
181 |
+
nw_mid1, nw_mid2, w_mid1, w_mid2, sw_mid1, sw_mid2,
|
182 |
+
s_mid1, s_mid2, se_mid1, se_mid2]
|
183 |
+
return central_coordindates
|
184 |
+
|
185 |
+
|
geocoder/geo_level11.py
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
"""
|
4 |
+
Created on Tue Aug 2 12:38:31 2022
|
5 |
+
|
6 |
+
@author: syed
|
7 |
+
"""
|
8 |
+
import regex_spatial
|
9 |
+
from utils import geoutil
|
10 |
+
|
11 |
+
|
12 |
+
north = ["north", "N'", "North", "NORTH"]
|
13 |
+
south = ["south", "S'", "South", "SOUTH"]
|
14 |
+
east = ["east", "E'", "East", "EAST"]
|
15 |
+
west = ["west", "W'", "West", "WEST"]
|
16 |
+
northeast = ["north-east", "NE'", "north east", "NORTH-EAST", "North East", "NORTH EAST"]
|
17 |
+
southeast = ["south-east", "SE'", "south east", "SOUTH-EAST", "South East", "SOUTH EAST"]
|
18 |
+
northwest = ["north-west", "NW'", "north west", "NORTH-WEST", "North West", "NORTH WEST"]
|
19 |
+
southwest = ["south-west", "SW'", "south west", "SOUTH-WEST", "South West", "SOUTH WEST"]
|
20 |
+
center = ["center","central", "downtown","midtown"]
|
21 |
+
def get_min_max(direction):
|
22 |
+
regex = regex_spatial.get_directional_regex()
|
23 |
+
direction_list = regex.split("|")
|
24 |
+
if direction in direction_list:
|
25 |
+
if direction in north:
|
26 |
+
return (337, 22)
|
27 |
+
if direction in northeast:
|
28 |
+
return (22, 67)
|
29 |
+
if direction in east:
|
30 |
+
return (67, 112)
|
31 |
+
if direction in southeast:
|
32 |
+
return (112, 157)
|
33 |
+
if direction in south:
|
34 |
+
return (157, 202)
|
35 |
+
if direction in southwest:
|
36 |
+
return (202, 247)
|
37 |
+
if direction in west:
|
38 |
+
return (247, 292)
|
39 |
+
if direction in northwest:
|
40 |
+
return (292, 337)
|
41 |
+
|
42 |
+
return None
|
43 |
+
|
44 |
+
|
45 |
+
def get_directional_coordinates_by_angle(coordinates, direction, minimum, maximum):
|
46 |
+
direction_coordinates = []
|
47 |
+
for p in coordinates:
|
48 |
+
if direction in north:
|
49 |
+
if p[2] >= minimum or p[2] <= maximum:
|
50 |
+
direction_coordinates.append(p)
|
51 |
+
|
52 |
+
else:
|
53 |
+
if p[2] >= minimum and p[2] <= maximum:
|
54 |
+
direction_coordinates.append(p)
|
55 |
+
return direction_coordinates
|
56 |
+
|
57 |
+
def get_directional_coordinates(coordinates, direction, centroid , minimum, maximum, is_midmid):
|
58 |
+
direction_coordinates = get_directional_coordinates_by_angle(coordinates, direction, minimum, maximum)
|
59 |
+
|
60 |
+
midmid1, midmid2= geoutil.get_midmid_point(centroid, direction_coordinates[0],direction_coordinates[-1], is_midmid)
|
61 |
+
if direction in south:
|
62 |
+
maxi = max(p[2] for p in direction_coordinates)
|
63 |
+
mini = min(p[2] for p in direction_coordinates)
|
64 |
+
index_mini = 0
|
65 |
+
index_maxi = 0
|
66 |
+
for idx,p in enumerate(direction_coordinates):
|
67 |
+
if p[2] == mini:
|
68 |
+
index_mini = idx
|
69 |
+
if p[2] == maxi:
|
70 |
+
index_maxi = idx
|
71 |
+
|
72 |
+
direction_coordinates.insert(index_maxi+1, midmid2)
|
73 |
+
direction_coordinates.insert(index_mini+1, midmid1)
|
74 |
+
else:
|
75 |
+
direction_coordinates.append(midmid2)
|
76 |
+
direction_coordinates.append(midmid1)
|
77 |
+
|
78 |
+
return direction_coordinates, midmid1, midmid2
|
79 |
+
|
80 |
+
def get_level1_coordinates(coordinates, centroid, direction, is_midmid):
|
81 |
+
min_max = get_min_max(direction)
|
82 |
+
if min_max is not None:
|
83 |
+
coordinates, mid1, mid2 = get_directional_coordinates(coordinates, direction, centroid,
|
84 |
+
min_max[0], min_max[1],is_midmid)
|
85 |
+
#centroid = geoutil.get_centroid(coordinates, centroid,min_max[0], min_max[1])
|
86 |
+
return coordinates, centroid, mid1, mid2
|
87 |
+
elif direction.lower() in center:
|
88 |
+
return get_central(coordinates, centroid, direction, is_midmid), centroid, None, None
|
89 |
+
else :
|
90 |
+
return coordinates, centroid, None, None
|
91 |
+
def get_central(coordinates, centroid, direction, is_midmid):
|
92 |
+
|
93 |
+
n_min_max = get_min_max("north")
|
94 |
+
n_coordinates=get_directional_coordinates_by_angle(coordinates, "north", n_min_max[0], n_min_max[1])
|
95 |
+
n_mid1, n_mid2 = geoutil.get_midmid_point(centroid,n_coordinates[0],n_coordinates[-1], is_midmid)
|
96 |
+
|
97 |
+
ne_min_max = get_min_max("north east")
|
98 |
+
ne_coordinates=get_directional_coordinates_by_angle(coordinates, "north east", ne_min_max[0], ne_min_max[1])
|
99 |
+
ne_mid1, ne_mid2 = geoutil.get_midmid_point(centroid,ne_coordinates[0],ne_coordinates[-1], is_midmid)
|
100 |
+
|
101 |
+
e_min_max = get_min_max("east")
|
102 |
+
e_coordinates=get_directional_coordinates_by_angle(coordinates, "east", e_min_max[0], e_min_max[1])
|
103 |
+
e_mid1, e_mid2 = geoutil.get_midmid_point(centroid,e_coordinates[0],e_coordinates[-1], is_midmid)
|
104 |
+
|
105 |
+
se_min_max = get_min_max("south east")
|
106 |
+
se_coordinates=get_directional_coordinates_by_angle(coordinates, "south east", se_min_max[0], se_min_max[1])
|
107 |
+
se_mid1, se_mid2 = geoutil.get_midmid_point(centroid,se_coordinates[0],se_coordinates[-1], is_midmid)
|
108 |
+
|
109 |
+
s_min_max = get_min_max("south")
|
110 |
+
s_coordinates=get_directional_coordinates_by_angle(coordinates, "south", s_min_max[0], s_min_max[1])
|
111 |
+
s_mid1, s_mid2 = geoutil.get_midmid_point(centroid,s_coordinates[0],s_coordinates[-1], is_midmid)
|
112 |
+
|
113 |
+
sw_min_max = get_min_max("south west")
|
114 |
+
sw_coordinates=get_directional_coordinates_by_angle(coordinates, "south west", sw_min_max[0], sw_min_max[1])
|
115 |
+
sw_mid1, sw_mid2 = geoutil.get_midmid_point(centroid,sw_coordinates[0],sw_coordinates[-1], is_midmid)
|
116 |
+
|
117 |
+
w_min_max = get_min_max("west")
|
118 |
+
w_coordinates=get_directional_coordinates_by_angle(coordinates, "west", w_min_max[0], w_min_max[1])
|
119 |
+
w_mid1, w_mid2 = geoutil.get_midmid_point(centroid,w_coordinates[0],w_coordinates[-1], is_midmid)
|
120 |
+
|
121 |
+
nw_min_max = get_min_max("north west")
|
122 |
+
nw_coordinates=get_directional_coordinates_by_angle(coordinates, "north west", nw_min_max[0], nw_min_max[1])
|
123 |
+
nw_mid1, nw_mid2 = geoutil.get_midmid_point(centroid,nw_coordinates[0],nw_coordinates[-1], is_midmid)
|
124 |
+
|
125 |
+
central_coordindates =[n_mid1, n_mid2, ne_mid1, ne_mid2, e_mid1, e_mid2,
|
126 |
+
se_mid1, se_mid2, s_mid1, s_mid2, sw_mid1, sw_mid2,
|
127 |
+
w_mid1, w_mid2, nw_mid1, nw_mid2]
|
128 |
+
return central_coordindates
|
129 |
+
|
130 |
+
|
geocoder/geo_level2.py
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#!/usr/bin/env python3
|
2 |
+
# -*- coding: utf-8 -*-
|
3 |
+
"""
|
4 |
+
Created on Tue Aug 2 12:38:31 2022
|
5 |
+
|
6 |
+
@author: syed
|
7 |
+
"""
|
8 |
+
import regex_spatial
|
9 |
+
from utils import geoutil
|
10 |
+
import geopandas as gpd
|
11 |
+
import pandas as pd
|
12 |
+
import re
|
13 |
+
from shapely.geometry import Polygon,mapping
|
14 |
+
import numpy as np
|
15 |
+
from shapely.geometry import Polygon, MultiPoint
|
16 |
+
from shapely.geometry.base import geom_factory
|
17 |
+
from shapely.geos import lgeos
|
18 |
+
from geocoder import geo_level1
|
19 |
+
|
20 |
+
#def get_common_coordinates(coordinates, level2):
|
21 |
+
#gdp.
|
22 |
+
|
23 |
+
def get_near(level2):
|
24 |
+
near = re.search(regex_spatial.get_near_regex(), level2)
|
25 |
+
if near is not None:
|
26 |
+
return near.group()
|
27 |
+
return None
|
28 |
+
|
29 |
+
def get_surrounding(level2):
|
30 |
+
surrounding = re.search(regex_spatial.get_surrounding_regex(), level2)
|
31 |
+
if surrounding is not None:
|
32 |
+
return surrounding.group()
|
33 |
+
return None
|
34 |
+
|
35 |
+
|
36 |
+
def sort_west(coords1, poly2, centroid):
|
37 |
+
#coords1 = mapping(poly1)["features"][0]["geometry"]["coordinates"]
|
38 |
+
coords2 = mapping(poly2)["features"][0]["geometry"]["coordinates"]
|
39 |
+
coord1 = []
|
40 |
+
coord2 = []
|
41 |
+
coord = []
|
42 |
+
for c in coords1:
|
43 |
+
pol = list(c[::-1])
|
44 |
+
coord1.extend(pol)
|
45 |
+
for c in coords2:
|
46 |
+
pol = list(c[::-1])
|
47 |
+
coord2.extend(pol)
|
48 |
+
coo1 = []
|
49 |
+
coo2 = []
|
50 |
+
for p in coord1:
|
51 |
+
angle = geoutil.calculate_bearing(centroid, p)
|
52 |
+
if angle >= 157 and angle <= 202:
|
53 |
+
coo1.append((p[0], p[1], angle))
|
54 |
+
for p in coord2:
|
55 |
+
angle = geoutil.calculate_bearing(centroid, p)
|
56 |
+
if angle >= 157 and angle <= 202:
|
57 |
+
coo2.append((p[0], p[1], angle))
|
58 |
+
coo1.extend(coo2)
|
59 |
+
return coo1
|
60 |
+
|
61 |
+
def get_directional_coordinates_by_angle(coordinates, centroid, direction, minimum, maximum):
|
62 |
+
direction_coordinates = []
|
63 |
+
for p in coordinates:
|
64 |
+
angle = geoutil.calculate_bearing(centroid, p)
|
65 |
+
if direction in geo_level1.east:
|
66 |
+
if angle >= minimum or angle <= maximum:
|
67 |
+
direction_coordinates.append(p)
|
68 |
+
|
69 |
+
else:
|
70 |
+
if angle >= minimum and angle <= maximum:
|
71 |
+
direction_coordinates.append(p)
|
72 |
+
#if(direction in geo_level1.west):
|
73 |
+
# direction_coordinates.sort(key=lambda k: k[2], reverse=True)
|
74 |
+
|
75 |
+
return direction_coordinates
|
76 |
+
|
77 |
+
def get_direction_coordinates(coordinates, centroid, level1):
|
78 |
+
min_max = geo_level1.get_min_max(level1)
|
79 |
+
if min_max is not None:
|
80 |
+
coord = get_directional_coordinates_by_angle(coordinates, centroid, level1, min_max[0], min_max[1])
|
81 |
+
return coord
|
82 |
+
return coordinates
|
83 |
+
|
84 |
+
|
85 |
+
def get_level2_coordinates(coordinates, centroid, level_2, level_1):
|
86 |
+
near = get_near(level_2)
|
87 |
+
surrounding = get_surrounding(level_2)
|
88 |
+
|
89 |
+
|
90 |
+
poly1 = Polygon(coordinates)
|
91 |
+
polygon1 = gpd.GeoSeries(poly1)
|
92 |
+
if near is not None:
|
93 |
+
poly2 = polygon1.buffer(0.0095, join_style=2)
|
94 |
+
if surrounding is not None:
|
95 |
+
poly2 = polygon1.buffer(0.012, join_style=2)
|
96 |
+
|
97 |
+
poly = poly2.difference(polygon1)
|
98 |
+
coords = mapping(poly)["features"][0]["geometry"]["coordinates"]
|
99 |
+
|
100 |
+
coord = []
|
101 |
+
for c in coords:
|
102 |
+
pol = list(c[::-1])
|
103 |
+
coord.extend(pol)
|
104 |
+
|
105 |
+
if level_1 is not None and level_1.lower() not in geo_level1.center:
|
106 |
+
coord = get_direction_coordinates(coord, centroid, level_1)
|
107 |
+
if level_1 in geo_level1.west:
|
108 |
+
coord = sort_west(coordinates,poly2, centroid)
|
109 |
+
|
110 |
+
print("Level 2 Coordinates")
|
111 |
+
for idx, p in enumerate(coord):
|
112 |
+
print(idx, p)
|
113 |
+
|
114 |
+
return coord, centroid
|
115 |
+
|
116 |
+
|
117 |
+
|