| |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| -> Python知识库 -> 如何利用FME 创建自己的功能软件 -> 正文阅读 |
|
|
[Python知识库]如何利用FME 创建自己的功能软件 |
|
目录 前言经过几个月修炼,之前更新的一篇利用django和fme实现模板继承的研究现在终于开花结果,今天悟空就来分享一下利用fme作为后台计算模型搭建数据分析web应用,创建自己的功能软件,让用户彻底脱离fme环境,创建属于自己的ui操作界面。 一、概述1、编程语言:JavaScript,python 2、开发框架:前端VUE3 ,后端django 3、数据库:数据表PostgreSql,进程管理数据库redis 4、开发工具:webstorm,pycharm 5、计算模型api:fme模板 二、开发思路1.前端开发本次开发主要采用前端后端分离式开发,前端使用vue3+element-plus搭建web应用页面,主要页面为登录页面、功能页面、成果下载页面。 (1)登录页面
?这个没啥好说的,主要注意的是要做一个导航守卫,登录成果后让系统从后台api拿到token值,根据是否有token值来判断页面是否跳转,如果没拿到token值则用户不能进入主页面。这部分比较通用,几乎任何应用都类似。 export default defineComponent({
setup() {
const loginForm={
username:'',
password:'',
};
let router=useRouter();
let store=useStore();
return {
router,
store,
loginForm,
};
},
mounted() {
let loginForm = JSON.parse(localStorage.getItem("loginForm"));
if (loginForm) {
this.loginForm = loginForm;
}
},
methods: {
onSubmit() {
let api = 'http://192.168.0.179:8000/lg/login/'
let router=this.router
window.localStorage.setItem("loginForm",this.loginForm.username);
axios.post(api,this.loginForm,{
timeout: 2000,
}).then(function(res:any){
alert('登录成功');
window.localStorage.setItem("token",res.data.token);
router.push({path:"/"});
//重新触发路由
location.reload()
(2)功能页面
?功能页面简洁大方为主,目前上线了3个功能集,都是以自定义表单的形式提交参数到后台,并得到成果,后续上线其他功能只需要简单新增子路由即可。
?以下是其中一个子页面代码,需要注意的如果是某些大文件传输,需要将文件二进制流打散,然后后端接受组合成完整文件,后期会考虑增加断点续传等功能。 <template>
<div class="page-box">
<vxe-toolbar>
</vxe-toolbar>
<el-form ref="form" :model="form" label-width="80px">
<el-row>
<el-col :span="24">
<div class="pagetit">尖锐角修复</div>
</el-col>
</el-row>
<el-row>
<el-col :span="10">
<el-form-item label="角度">
<el-input v-model="forms.angel" placeholder="尖角判定最大角度"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="10">
<el-form-item label="面积">
<el-input v-model="forms.area" placeholder="尖角部分面积改变大小"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="18">
<el-form-item label="文件上传">
<el-upload
multiple
ref="mYupload"
:on-change="fileget"
class="upload-demo"
action="111"
:auto-upload="false"
>
<template #trigger>
<el-button type="primary">需要修复的shp文件</el-button>
</template>
<el-button type="primary" @click="clearFiles">
清空
</el-button>
</el-upload>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="18">
<el-form-item>
<el-button type="primary" @click="onSubmit">提交数据</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import axios from "axios";
export default defineComponent({
setup() {
var fileList=[];
var file= {};
var dialogImageUrl= '';
var dialogVisible= false;
const forms=ref({
angel:'',
area:'',
});
return {
file:{},
fileList:[],
forms,
};
},
methods: {
fileget(file){
this.fileList.push(file.raw)
console.log(this.fileList)
},
clearFiles() {
this.$refs["mYupload"].clearFiles();
},
onSubmit() {
let api = 'http://192.168.0.179:8000/api/test/';
let fd = new FormData();
//let username= window.username
let name = window.localStorage.getItem('loginForm');
for(var i=0;i<this.fileList.length;i++){
fd.append('file',this.fileList[i]);;
}
//传文件
fd.append('angel',this.forms.angel);//传其他参数
fd.append('area',this.forms.area);
fd.append('name',name);
axios.post(api,fd,{
headers: {'Content-Type': 'multipart/form-data'},
timeout: 200000,
}).then(function(res){
alert('提交成功');
})
this.fileList=[];
this.$refs["mYupload"].clearFiles();
this.forms={
angel:'',
area:'',
};
// return false//屏蔽了action的默认上传
},
},
})
</script>
<style lang="scss" scoped>
.up-load{
width: 50vw;
margin: 50px auto;
>div{
margin-top: 20px;
}
.up-title{
text-align: center;
font-size: 30px;
font-weight: 600;
}
.up-one{
height: 70px;
overflow: hidden;
}
.property{
padding: 0 50px;
text-align: center;
>div{
padding: 10px;
font-weight: 600;
}
}
}
/deep/.vxe-button--content{color: #fff;}
/deep/.vxe-button.type--button:hover,.vxe-button.type--button.active{background: #2D94FC !important; border-color: #2D94FC!important;}
</style>
(3)下载页面我们所有表单提交都采用ajax异步请求,请求完成后,后端接收前端数据,储存数据库,触发fme计算模型。fme模板运行完毕后会和后端交互,自动生成下载链接,并渲染到前端。 表单提交后会立即生成任务,后台计算完成后会自动更新任务状态。
fme模板执行成功后自动渲染下载链接
fme模板运行失败,也会更新任务状态让用户从新检查自己的提交参数
点击下载链接,成功下载计算后成果。
点击删除按钮则自动删除该任务在数据库的位置,以及对应的下载文件。
?2.后端开发后端开发采用django和django的扩展库drf来快速生成接口,采用redis和celery来管理fme进程以便于应付高并发任务队列情况。 值得一提的是celery这个python库,能实现百万级的进程管理,成功的让我们的后台模板有序高效的执行。经过测试,celery在处理高请求量且较为复杂的fme模板甚至有媲美fmeserver的效率。
?当然唯一的缺陷也非常明显,就是fmedesktop最多只支持8进程同时运行,不过要克服这一难题也不是没有办法,可以组建分布式celery,让多台机器为一个django提供计算服务。要组建分布式的话,所涉及的技术也更加的难,要考虑资源分配,任务调度,以及多台机器的连接稳定。redis和数据库以及本地磁盘都得建立多台机内网共享。 后端还需要攻克的一点则是 输出成果的渲染,因为我们的用户的多个,他们执行的任务是不同的,后端需要写逻辑,根据前端的反馈的用户名信息,从数据库调用该用户的任务来反馈给前端,不然就会导致任务共享,用户则不知道自己执行的任务是哪一个。 以下是部分后端代码。
?3.FME模板调用调用模板采用python触发dos指令来传递前端参数,并调用fme模板,需要注意传统os调用会出问题,因为传统os调用是异步携程执行。这样会和celery出现冲突,我们需要subprocess库来调用模板,同步执行。 二、发布上线采用iis服务器发布django任务,具体可以参考该博主的博客。Django--4 Django项目在Win10 + IIS服务器部署上线运行_liuning2008的博客-CSDN博客_django项目部署到服务器 windowsz 整体项目框架就是这样,temp存放临时缓存文件,fmw存放模板文件。我设置了windos用户计划,定期清空临时文件防止磁盘爆满。 总结 爆肝多个月终于是将全套功能实现了,看似简单的功能,简单的逻辑,其实涉及了庞大的技术量,中途踩的坑那是一个比一个多,尤其是vue的生命周期和路由分发,耗费了我大量时间才勉强实现效果。有兴趣的小伙伴可以先从前端js,html5,css3开始学起,再掌握一门后端框架,推荐django和flask。最终的成果是让我非常满意的,同时也感谢我的前端大佬小洋人,给我恶补了不少vue的知识点。该研究最大的特点就是可以让用户脱离fme环境,脱离配置各种python库的烦恼,脱离电脑设备跟不上的困境,只需要一个浏览器,就可以完成大量复杂且耗费人工的工作,后期我会陆续上线功能集,并准备把我之前的搞深度学习涉及的不少模板也上线了。 |
|
|
|
|
| 上一篇文章 下一篇文章 查看所有文章 |
|
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
| 360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年11日历 | -2025/11/29 2:51:28- |
|
| 网站联系: qq:121756557 email:121756557@qq.com IT数码 |