我想建立一个新闻互动地图。该应用程序将获取网站的最新新闻,尝试正则表达式新闻位置,如果是,则将它们作为点插入地图中,用户可以在其中导航并单击这些点来查看新闻。
为此,我让 ChatGPT 创建了一个 geojson 特征集合文件,其中包含城市的特征点及其几何坐标,然后我用获取的数据进行丰富,并将它们插入到properties.name、标题、日期和 url 中新闻网站如下:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
23.6481,
37.9439
]
},
"properties": {
"name": "Πειραιάς",
"title": "Πειραιάς: Δύο συλλήψεις για ληστείες σε βάρος ανηλίκων",
"date": "Friday, 24 May 2024 19:27:24",
"url": "https://www.news247.gr/ellada/peiraias-dio-sillipseis-gia-listeies-se-varos-anilikon/"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
22.8812,
41.00129999999999
]
},
"properties": {
"name": "Κιλκίς",
"title": "Έγκλημα στο Κιλκίς: Προσωρινά κρατούμενοι οι δύο ανήλικοι κατηγορούμενοι",
"date": "Thursday, 23 May 2024 17:17:47",
"url": "https://www.news247.gr/ellada/egklima-sto-kilkis-prosorina-kratoumenoi-oi-dio-anilikoi-katigoroumenoi/"
}
}
]
}
我精心设计的配置如下:
{
"version": "v1",
"config": {
"visState": {
"filters": [],
"layers": [],
"interactionConfig": {}
},
"mapState": {
"bearing": -4.928571428571431,
"dragRotate": "True",
"latitude": 37.97,
"longitude": 23.72,
"pitch": 30,
"zoom": 8.655984704565685,
"isSplit": "False"
},
"mapStyle": {
"styleType": "light",
"topLayerGroups": {},
"visibleLayerGroups": {
"label": "True",
"road": "False",
"border": "True",
"building": "False",
"water": "True",
"land": "True"
}
}
}
}
我的代码如下:
from bs4 import BeautifulSoup
from keplergl import KeplerGl
from datetime import datetime
import requests
import json
import re
import time
import pprint
import html
import random
def get_sitemap():
return requests.get('https://www.news247.gr/news-sitemap.xml').text
def fix_minor(title):
fixed_title = title.replace('\n', ' ')
# Replace multiple spaces with a single space
fixed_title = ' '.join(fixed_title.split())
fixed_title = html.unescape(fixed_title)
return fixed_title
def get_news_info(news):
url = news.find('loc').text
date = datetime.fromisoformat(news.find('publication_date').text).strftime("%A, %d %B %Y %H:%M:%S")
title = fix_minor(news.find('title').text)
return {'title': title, 'date': date, 'url': url}
def load_geoJson():
with open('geo_gr.json', 'r') as file:
geo = json.loads(file.read())
return geo
def load_config():
with open('ub.json', 'r') as cc:
custom_config = json.loads(cc.read())
return custom_config
# main
# get latest news
soup = BeautifulSoup(get_sitemap(), 'xml')
news = soup.find_all('url')
# append latest news to list
all_news = []
for item in news:
all_news.append(get_news_info(item))
# load geo json and perform geo regex
tagList = []
locations = []
geo = load_geoJson()
features = []
out_geo = {}
out_geo.update({"type": "FeatureCollection"})
for item in all_news:
for location in geo['features']:
re_location = re.search(location['properties']['name'], item['title'])
if re_location:
location['properties'].update({'title':item['title'], 'date':item['date'], 'url':item['url']})
for coord in range(len(location['geometry']['coordinates'])):
location['geometry']['coordinates'][coord] = location['geometry']['coordinates'][coord] + round(random.uniform(0.001, 0.003), 4)
features.append(location)
out_geo.update({'features':features})
map_ = KeplerGl(height=600, data={'feature_collection': out_geo}, config=load_config())
# Save the map to an HTML file
map_.save_to_html(file_name="index1.html")
代码确实可以工作,但我想解决的问题是配置文件的编辑。更具体地说,我找不到在 config.visState.layer 中正确插入数据的方法,以便我可以执行基本的图层编辑,例如更改颜色、点半径、描边等,而无法获得默认设置。
提前感谢您的帮助,对于给您带来的任何不便,我深表歉意。
我建议使用 config.yaml 文件循环更新层配置,以便每个层使用配置 yaml 作为模板来构建层配置。
这是我使用过的 yaml 文件的示例
层数: id:“<< name >>” 类型:“点” 配置: 数据ID:“<< name >>” 标签:“<< name >>” 可见:true 颜色:“<< color >>” 突出显示颜色:“<< highlightColor >>” 可见配置: 不透明度:“<< opacity >>” 描边不透明度:0.8 厚度:“<< thickness >>” 抚摸:真实 填充:真实 半径:“<< radius >>” 列: 纬度:“<< latitude_column_name >>” 长:“<< longitude_column_name >>”
然后您可以使用一些默认值和代码来检查输入数据中是否存在某个值,如果不存在,则简单地使用 yaml 文件中的默认值。