0

0

将Python逻辑与交互式Web地图融合:实现点击地图区域触发计算与用户输入

花韻仙語

花韻仙語

发布时间:2025-11-15 13:24:01

|

854人浏览过

|

来源于php中文网

原创

将python逻辑与交互式web地图融合:实现点击地图区域触发计算与用户输入

本文旨在解决如何将Python地理空间地图(使用Folium)的交互性与用户输入及Python后端计算(如线性规划)结合的问题。我们将探讨Folium在复杂交互方面的局限性,并提供两种主要解决方案:一是利用Streamlit或Gradio等Python交互式UI框架快速构建应用,二是采用Flask后端与JavaScript前端的全栈Web开发模式,详细阐述如何实现地图点击事件、获取用户输入并触发后端计算。

1. 挑战与Folium的局限性

原始需求是在用户点击地图上的区域(例如行政区)时,弹出一个窗口,要求用户输入“需求(Demand)”和“投资(Investment)”两个值,然后基于这些输入执行一个Python线性规划(LP)计算。

最初的代码片段展示了如何使用folium和geopandas生成一个包含行政区划的交互式地图,并在点击时显示一个简单的弹出窗口。另一个片段则定义了一个lp函数,用于执行线性规划计算,并通过input()函数获取用户输入。

然而,这种直接结合存在以下核心问题:

立即学习Python免费学习笔记(深入)”;

  • Folium的交互性限制: folium主要用于生成静态的HTML地图文件,其内置的folium.Popup通常用于显示预设的文本或HTML内容。虽然它提供了一些基本的交互(如缩放、平移、显示提示信息),但要实现复杂的表单输入、事件监听和数据提交,并与Python后端进行实时通信,Folium本身并不直接支持。它生成的是客户端HTML,无法直接调用服务器端的Python函数。
  • input()函数的适用性: Python的input()函数是一个阻塞式的控制台输入函数,它在程序运行时暂停执行,等待用户在命令行界面输入数据。这在Web环境中是完全不适用的,Web应用需要通过浏览器界面获取用户输入。

因此,要实现点击地图区域后弹出输入框并触发Python计算的功能,我们需要引入更强大的Web交互机制。

2. 方案一:基于Python的交互式UI框架

对于希望快速构建具有交互功能的Web应用,且主要使用Python的开发者,Streamlit和Gradio是优秀的解决方案。它们提供了一套高级组件,能够将Python代码直接转化为交互式Web界面,无需深入了解前端技术(HTML/CSS/JavaScript)。

2.1 Streamlit

Streamlit以其极简的API和快速原型开发能力而闻名。它提供了st.map等地图组件,并且可以方便地集成各种输入控件。

核心思路:

LLaMA
LLaMA

Meta公司发布的下一代开源大型语言模型

下载
  1. 使用Streamlit的地图组件展示地理数据。
  2. 通过Streamlit的输入组件(如st.number_input)获取用户输入。
  3. 在Streamlit应用的回调函数中调用Python的lp计算逻辑。

优点:

  • 纯Python开发,无需前端知识。
  • 快速构建原型和数据应用。
  • 内置了许多常用的UI组件。

概念性代码示例(Streamlit风格):

import streamlit as st
import geopandas as gpd
import json
import pulp
# 假设 consts 函数已定义并能正确工作
# from your_module import consts

# 模拟 consts 函数,实际应从文件读取
def consts(district):
    # 示例数据,实际应从Excel读取
    data = {
        "Maputo City": {"A": "10", "B": "20", "C": "30"},
        "Matola": {"A": "15", "B": "25", "C": "35"},
        # ... 更多地区数据
    }
    return data.get(district, {"A": "1", "B": "1", "C": "1"})

def lp_streamlit(district_name, demand, investment):
    """
    修改后的lp函数,直接接收参数而不是通过input()获取
    """
    model = pulp.LpProblem(name=f"Lp_{district_name}", sense=pulp.const.LpMinimize)

    district_consts = consts(district_name)
    A = float(district_consts.get("A"))
    B = float(district_consts.get("B"))
    C = float(district_consts.get("C"))

    x_1 = pulp.LpVariable(name="x_1", lowBound=0)
    x_2 = pulp.LpVariable(name="x_2", lowBound=0)
    x_3 = pulp.LpVariable(name="x_3", lowBound=0)

    obj_func = 41*x_1 + 11*x_2 + 24*x_3
    model += obj_func

    model += (x_1 + x_2 + x_3 >= demand)
    model += (A*x_1 + B*x_2 + C*x_3 <= investment)

    status = model.solve()
    results = {}
    if pulp.LpStatus[status] == "Optimal":
        for var in model.variables():
            results[var.name] = var.value()
    else:
        results["status"] = pulp.LpStatus[status]
    return results

st.title("莫桑比克地区数据分析")

# 假设你有一个包含地理信息和地区名称的GeoDataFrame
# 例如:districts = gpd.read_file("Distritos.shp")
# 为简化,这里创建一个模拟的GeoDataFrame
data = {
    'ADM2_PT': ['Maputo City', 'Matola', 'Boane'],
    'geometry': [
        gpd.points_from_xy([32.58, -25.97]).iloc[0],
        gpd.points_from_xy([32.48, -25.87]).iloc[0],
        gpd.points_from_xy([32.38, -26.07]).iloc[0]
    ]
}
districts = gpd.GeoDataFrame(data, crs="EPSG:4326")

# Streamlit的地图组件可以直接显示GeoDataFrame
st.subheader("选择一个地区进行分析")
st.map(districts) # 注意:st.map功能相对基础,更复杂的地图可能需要使用st.pydeck_chart或Folium嵌入

# 假设用户通过其他方式选择了地区,例如下拉菜单
selected_district = st.selectbox(
    "请选择一个地区:",
    districts['ADM2_PT'].tolist()
)

if selected_district:
    st.subheader(f"为 {selected_district} 输入参数:")
    demand_input = st.number_input("需求 (Demand):", min_value=0.0, value=100.0, step=1.0)
    investment_input = st.number_input("投资 (Investment):", min_value=0.0, value=500.0, step=1.0)

    if st.button("运行计算"):
        with st.spinner("正在计算中..."):
            lp_results = lp_streamlit(selected_district, demand_input, investment_input)
            st.write("### 计算结果:")
            st.json(lp_results)

2.2 Gradio

Gradio是另一个用于快速构建机器学习模型Web界面的Python库,但它同样适用于任何Python函数。它也提供了地图组件和各种输入输出组件。

核心思路:

  1. 定义一个Python函数,该函数接收用户输入(地区名、需求、投资)并返回计算结果。
  2. 使用Gradio的gr.Interface将该函数包装成Web应用,并配置相应的输入输出组件。

优点:

  • 快速为Python函数创建Web界面。
  • 支持多种输入输出类型。
  • 尤其适合演示和分享Python模型。

概念性代码示例(Gradio风格):

import gradio as gr
import geopandas as gpd
import pulp
# 假设 consts 函数已定义并能正确工作
# from your_module import consts

# 模拟 consts 函数,实际应从文件读取
def consts(district):
    # 示例数据
    data = {
        "Maputo City": {"A": "10", "B": "20", "C": "30"},
        "Matola": {"A": "15", "B": "25", "C": "35"},
        # ... 更多地区数据
    }
    return data.get(district, {"A": "1", "B": "1", "C": "1"})

def lp_gradio(district_name, demand, investment):
    """
    修改后的lp函数,直接接收参数而不是通过input()获取
    """
    model = pulp.LpProblem(name=f"Lp_{district_name}", sense=pulp.const.LpMinimize)

    district_consts = consts(district_name)
    A = float(district_consts.get("A"))
    B = float(district_consts.get("B"))
    C = float(district_consts.get("C"))

    x_1 = pulp.LpVariable(name="x_1", lowBound=0)
    x_2 = pulp.LpVariable(name="x_2", lowBound=0)
    x_3 = pulp.LpVariable(name="x_3", lowBound=0)

    obj_func = 41*x_1 + 11*x_2 + 24*x_3
    model += obj_func

    model += (x_1 + x_2 + x_3 >= demand)
    model += (A*x_1 + B*x_2 + C*x_3 <= investment)

    status = model.solve()
    results = {}
    if pulp.LpStatus[status] == "Optimal":
        for var in model.variables():
            results[var.name] = var.value()
    else:
        results["status"] = pulp.LpStatus[status]
    return results

# 假设 districts 是一个GeoDataFrame,包含 'ADM2_PT' 列
# For Gradio, we might just use a dropdown for districts if map interaction is complex
# districts = gpd.read_file("Distritos.shp")
# district_choices = districts['ADM2_PT'].tolist()
district_choices = ["Maputo City", "Matola", "Boane"] # 简化示例

iface = gr.Interface(
    fn=lp_gradio,
    inputs=[
        gr.Dropdown(district_choices, label="选择地区"),
        gr.Number(label="需求 (Demand)", value=100.0),
        gr.Number(label="投资 (Investment)", value=500.0)
    ],
    outputs="json", # 输出可以是文本、JSON等
    title="地区线性规划计算器",
    description="选择一个地区并输入需求和投资进行计算。"
)

# iface.launch() # 在本地运行Gradio应用

3. 方案二:构建全栈Web应用(Flask + JavaScript)

对于需要高度定制化界面、复杂交互逻辑或大规模部署的Web应用,采用传统的全栈Web开发模式(后端框架如Flask/FastAPI,前端技术如HTML/CSS/JavaScript及其框架如React/Vue/Angular)是更专业的选择。

本节将以Flask作为后端框架,结合JavaScript实现Folium地图的交互。

3.1 核心思路

  1. 后端 (Flask):
    • 提供一个Web服务器,用于渲染包含Folium地图的HTML页面。
    • 提供API接口,接收前端发送的地区名称、需求和投资数据。
    • 在API接口中调用Python的lp函数进行计算,并将结果返回给前端。
  2. 前端 (HTML/JavaScript):
    • 在HTML页面中嵌入Folium地图。
    • 关键: 监听Folium地图上GeoJson层的点击事件。
    • 当点击事件发生时,获取被点击的地区名称。
    • 在页面上动态显示一个模态框(Modal)或表单,收集用户的“需求”和“投资”输入。
    • 使用JavaScript的fetch API将收集到的数据发送到Flask后端API。
    • 接收后端返回的计算结果,并在页面上展示。

3.2 后端实现 (Flask)

首先,确保lp和consts函数能够接收参数而不是通过input()获取。

# app.py
from flask import Flask, render_template, request, jsonify
import folium
import geopandas as gpd
import json
import pulp
import openpyxl
import os

app = Flask(__name__)

# --- 辅助函数:从Excel加载常量 ---
def consts(district):
    values = {}
    # 确保Excel文件路径正确,这里假设在项目根目录
    excel_path = os.path.join(os.path.dirname(__file__), 'Dados_py.xlsx') 
    try:
        book = openpyxl.load_workbook(excel_path)
        worksheet = book["Dados"]
        for row in worksheet.iter_rows(min_row=1, values_only=True):
            if row[0] == district:
                values = {"A": str(row[1]), "B": str(row[2]), "C": str(row[3])}
                break
    except FileNotFoundError:
        print(f"Error: Excel file not found at {excel_path}")
    return values

# --- 线性规划计算函数 ---
def lp(district_name, demand, investment):
    model = pulp.LpProblem(name=f"Lp_{district_name}", sense=pulp.const.LpMinimize)

    district_consts = consts(district_name)
    if not district_consts:
        return {"error": f"No constants found for district: {district_name}"}

    A = float(district_consts.get("A"))
    B = float(district_consts.get("B"))
    C = float(district_consts.get("C"))

    x_1 = pulp.LpVariable(name="x_1", lowBound=0)
    x_2 = pulp.LpVariable(name="x_2", lowBound=0)
    x_3 = pulp.LpVariable(name="x_3", lowBound=0)

    obj_func = 41*x_1 + 11*x_2 + 24*x_3
    model += obj_func

    model += (x_1 + x_2 + x_3 >= demand)
    model += (A*x_1 + B*x_2 + C*

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python Flask框架
Python Flask框架

本专题专注于 Python 轻量级 Web 框架 Flask 的学习与实战,内容涵盖路由与视图、模板渲染、表单处理、数据库集成、用户认证以及RESTful API 开发。通过博客系统、任务管理工具与微服务接口等项目实战,帮助学员掌握 Flask 在快速构建小型到中型 Web 应用中的核心技能。

104

2025.08.25

Python Flask Web框架与API开发
Python Flask Web框架与API开发

本专题系统介绍 Python Flask Web框架的基础与进阶应用,包括Flask路由、请求与响应、模板渲染、表单处理、安全性加固、数据库集成(SQLAlchemy)、以及使用Flask构建 RESTful API 服务。通过多个实战项目,帮助学习者掌握使用 Flask 开发高效、可扩展的 Web 应用与 API。

81

2025.12.15

Python FastAPI异步API开发_Python怎么用FastAPI构建异步API
Python FastAPI异步API开发_Python怎么用FastAPI构建异步API

Python FastAPI 异步开发利用 async/await 关键字,通过定义异步视图函数、使用异步数据库库 (如 databases)、异步 HTTP 客户端 (如 httpx),并结合后台任务队列(如 Celery)和异步依赖项,实现高效的 I/O 密集型 API,显著提升吞吐量和响应速度,尤其适用于处理数据库查询、网络请求等耗时操作,无需阻塞主线程。

28

2025.12.22

Python 微服务架构与 FastAPI 框架
Python 微服务架构与 FastAPI 框架

本专题系统讲解 Python 微服务架构设计与 FastAPI 框架应用,涵盖 FastAPI 的快速开发、路由与依赖注入、数据模型验证、API 文档自动生成、OAuth2 与 JWT 身份验证、异步支持、部署与扩展等。通过实际案例,帮助学习者掌握 使用 FastAPI 构建高效、可扩展的微服务应用,提高服务响应速度与系统可维护性。

251

2026.02.06

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1946

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

656

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2399

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

47

2026.01.19

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.9万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

CSS教程
CSS教程

共754课时 | 42.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号