并行任务进度监控
import psycopg2 as pg
def doDB(sql,flag): # flag=1是操作增删改,2是查
conn = pg.connect(database="i_twin", user="postgres", password="123456", host="192.168.1.96",
port="5432")
cur = conn.cursor()
cur.execute(sql)
if flag==1:conn.commit()
if flag==2:res = cur.fetchall() # 或fetchone()
cur.close()
conn.close()
if flag==2:return res
import socket
# 获取本机计算机名称
hostname = socket.gethostname()
print(hostname) # LAPTOP-12FVS7AP
# 获取本机ip
ip = socket.gethostbyname(hostname)
print(ip) # 192.168.150.30
import random
import time
import threading
import os
# 并行任务进度监控,最后启个接口通过id查询进度状态
def st(x):
print('do',x)
c=random.random()*30
time.sleep(c)
print('done',x)
s="select * from z_sch where id='%s' "%(id)
info=doDB(s,2)[0]
s="update z_sch set susnum=%s,sch=%s,updatetime=%s where id='%s' "\
%(info[4]+1,(info[4]+1)/info[3],round(time.time()),id)
doDB(s,1)
# 开始创建一条数据
id='3'
num=4 # 任务数
t=round(time.time())
# id pid ip num susnum sch state ctime utime
# 唯一id,进程号int,服务器ip,需计算的点数,完成数,sch进度float,state状态,创建时间戳time.time,更新时间戳
# [('1dri32itn2j3r', 234, '12.12.12.12', 5, 4, 44.0, '执行中', 1649322201, 1649322222)]
s="insert into z_sch values ('%s',%s,'%s',%s,%s,%s,'%s',%s,%s) "%(id,os.getpid(),ip,num,0,0,'执行中',t,t)
doDB(s,1)
# exit()
# 主程序 并行
threads = []
for x in range(num):
thread = threading.Thread(target=st, args=(x,))
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
# 结束把状态改为完成
s="update z_sch set state='完成' where id='%s' "%(id)
doDB(s,1)
print('Main end')
python接口服务
可以用自带的http.server,nohup python -m http.server 8001 &,http://192.168.6.103:8001/,不过不方便,支持不够(Unsupported method),更好的有wsgi server和wsgi application
fastapi+uvicorn,wsgiref(麻烦)
可以用django、flask
通信数据包的传输、协议的设计,socket、restful
restful规范:get请求数据、post新增数据、put更新数据、delete删除数据
接口没什么特别的规范,能交互、稳定就是好接口
import os
import flask, json
from flask import request
# flask: web框架,通过flask提供的装饰器@server.route()将普通函数转换为服务
server = flask.Flask(__name__) # 创建一个服务,把当前这个python文件当做一个服务
# server.config['JSON_AS_ASCII'] = False
# @server.route()可以将普通函数转变为服务 登录接口的路径、请求方式
@server.route('/get', methods=['get'])
def doget():
a=request.url
print(a) # http://127.0.0.1:8888/get?id=1 ,split?后的参数做后续操作
try:
with open(os.path.dirname(__file__)+'a.json') as f:
data=json.load(f)
print('get data',data)
return data
except FileNotFoundError:
return {'data':None}
@server.route('/post1', methods=[ 'post'])
def dopost1():
# 获取通过url请求传参的json数据
a=request.data
if a==b'':return {'no data': 200}
a=json.loads(a)
print('asd',a,type(a))
if a == dict(): return {'data': None} # 空数据或不传数据
id=a['id']
print(id)
# a1 = request.values.keys() # 传dict而不是json
# if a1==set():return {'data':None} # 空数据或不传数据
# ee=dict()
# for i in a1:
# print(i,request.values.getlist(i)) # a ['2', '3'] 12 ['zz'] ,get()不全
# ee[i]=request.values.getlist(i)
# print(list(a1),type(a1))
with open(os.path.dirname(__file__)+'\\'+id+'.json','w') as f: # 写数据
json.dump(a,f) # 传参dict,file
print(os.path.dirname(__file__))
print('write sus')
os.system('python cc.py '+id) # 写入结果文件
with open(os.path.dirname(__file__)+'\\'+id+'end.json') as f: # 读取结果文件,同步返回
data=json.load(f)
print(data)
return json.dumps(data)
@server.route('/post2', methods=[ 'post'])
def dopost2():
# 获取通过url请求传参的json数据
a=request.data
if a==b'':return {'no data': 200}
a=json.loads(a)
print('asd',a,type(a))
if a == dict(): return {'data': None} # 空数据或不传数据
id=a['id']
print(id)
with open(os.path.dirname(__file__)+'\\'+id+'.json','w') as f: # 写数据
json.dump(a,f) # 传参dict,file
print(os.path.dirname(__file__))
print('write sus')
os.system('python cc.py '+id) # 阻塞
# # 子线程,不阻塞
# import threading
# def do():
# os.system('python cc.py '+id)
# a = threading.Thread(target=do)
# a.start()
return {'suc sent data':200}
if __name__ == '__main__':
server.run(debug=True, port=8888, host='0.0.0.0')
# 指定端口、host,0.0.0.0代表不管几个网卡,任何ip都可以访问
import requests
import json
url1='http://192.168.150.30:8888/get'
# url1='http://192.168.150.30:8888/get?id=2'
url2='http://192.168.150.30:8888/post2'
ddd={'a':[2,3],12:'zz',22:[3,2,1,2],'id':'asd2'}
# ddd={'a':'zz'}
# ddd={}
a=requests.post(url2,json.dumps(ddd)) # post给数据
# a=requests.post(url2)
print(a) # <Response [200]>
print(a.text) # {"suc sent data": 200}
# exit()
b=requests.get(url1) # get拿数据
# b=requests.get(url1,params={'id':1}) # get拿数据 ,传参等同于 ?id=1
bv=b.json()# 获取数据
print(b) # <Response [200]>
print(bv,type(bv)) # {'data': None} <class 'dict'>
经纬度计算
经纬度算距离、角度、相对位置
from math import radians,cos,sin,atan2,degrees,sqrt,asin
def getgeoda(lon1, lat1, lon2, lat2):
'''
经纬度间距离(m)、两点间方位角(北顺,东逆就是-x+90)
等价于geopy.distance.great_circle(q1, q2).meters
'''
# 经纬度转换成弧度
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
distance = 2 * asin(sqrt(a)) * 6371.009 * 1000 # 地球平均半径,6371km
y = sin(dlon) * cos(lat2)
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon)
brng = degrees(atan2(y, x))
return int(distance),round(brng%360,2)
# print(getgeoda(113.3097, 23.3922,113.3192, 23.5094))
def getcoord(lon1, lat1, lon2, lat2): # 以1为坐标中心的2的坐标,取整,m
d,ang=getgeoda(lon1, lat1, lon2, lat2)
ang=-ang+90 # 方位角是北顺,正常的角度是东逆
return (int(d*cos(radians(ang))),int(d*sin(radians(ang))))
经纬度算距离、一定距离的经纬度
import math
class LonLatPoint():
def __init__(self,lon,lat):
self.lon=lon
self.lat=lat
def getLat(self) :
return self.lat
def getLon(self):
return self.lon
def getX(self):
return self.lon
def getY(self):
return self.lat
def getCosY(self):
return math.cos(self.lat * 0.017453292519943295)
def getCosX(self):
return math.cos(self.lon * 0.017453292519943295)
def getSinY(self):
return math.sin(self.lat * 0.017453292519943295)
def getSinX(self):
return math.sin(self.lon * 0.017453292519943295)
class Ellipsoid():
buU = 6378137
dDD = 298.257223563
dDC = (buU * (1 - 1 / dDD))
dDE = ((2 - 1 / dDD) / dDD)
dDF = (1 / dDD)
a2 = buU * buU
b2 = dDC * dDC
dDH = ((a2 - b2) / b2)
def getA(self):
return self.buU
def getB(self):
return self.dDC
def getF(self):
return self.dDF
def getEMinor2(self):
return self.dDH
ELLIPSOID = Ellipsoid()
def calPointOnCircle(aPoint, distance_meter, aAzimuth) :
if (distance_meter < 1.0E-4) :
return aPoint
tanu1 = ELLIPSOID.getB() * (aPoint.getSinY() / aPoint.getCosY()) / ELLIPSOID.getA()
cosu1 = 1 / math.sqrt(1 + tanu1 * tanu1)
sinu1 = cosu1 * tanu1
alpha12 = aAzimuth * 0.017453292519943295
cosalpha12 = math.cos(alpha12)
sinalpha12 = math.sin(alpha12)
f16 = ELLIPSOID.getF() / 16
sigma1 = math.atan2(tanu1, cosalpha12)
sinalpha = cosu1 * sinalpha12
sin2alpha = sinalpha * sinalpha
cos2alpha = 1 - sin2alpha
up2 = cos2alpha * ELLIPSOID.getEMinor2()
aa = 1 + up2 / 16384 * (4096 + up2 * (-768 + up2 * (320 - 175 * up2)))
bb = up2 / 1024 * (256 + up2 * (-128 + up2 * (74 - 47 * up2)))
sbA=0
sigma = sbA = distance_meter / (ELLIPSOID.getB() * aa)
cossigma = math.cos(sigma)
sinsigma = math.sin(sigma)
i = 0
cos_twosigma_m=0
while i < 4:
two_sigma_m = 2 * sigma1 + sigma
cos_twosigma_m = math.cos(two_sigma_m)
a1 = cossigma * (-1 + 2 * cos_twosigma_m * cos_twosigma_m)
a2 = cos_twosigma_m * (-3 + 4 * sinsigma * sinsigma)*(-3 + 4 * cos_twosigma_m * cos_twosigma_m)
delta_sigma = bb * sinsigma * (cos_twosigma_m + bb / 4 * (a1 - bb / 6 * a2))
sigma_old = sigma
sigma = sbA + delta_sigma
cossigma = math.cos(sigma)
sinsigma = math.sin(sigma)
if abs(sigma - sigma_old) < 1.0E-10 :
break
i +=1
a1 = sinu1 * cossigma + cosu1 * sinsigma * cosalpha12
a3 = sinu1 * sinsigma - cosu1 * cossigma * cosalpha12
a2 = (1 - ELLIPSOID.getF()) *math.sqrt(sin2alpha + a3 * a3)
phi2 = 57.29577951308232 * math.atan2(a1, a2)
a1 = sinsigma * sinalpha12
a2 = cosu1 * cossigma - sinu1 * sinsigma * cosalpha12
lambdarad = math.atan2(a1, a2)
C = f16 * cos2alpha * (4 + ELLIPSOID.getF() * (4 - 3 * cos2alpha))
a1 = cos_twosigma_m + C * cossigma * (-1 + 2 * cos_twosigma_m * cos_twosigma_m)
a2 = (1 - C) *ELLIPSOID.getF() * sinalpha * (sigma + C * sinsigma * a1)
omegarad = lambdarad - a2
lambda2 = aPoint.getX() + 57.29577951308232 * omegarad
return (round(lambda2,4), round(phi2,4))
def geodesicDistance(aP1, aP2) :
aLon1 = aP1.getX()
aLat1 = aP1.getY()
aLon2 = aP2.getX()
aLat2 = aP2.getY()
tanu1 = ELLIPSOID.getB() * math.tan(aLat1 * 0.017453292519943295) / ELLIPSOID.getA()
tanu2 = ELLIPSOID.getB() * math.tan(aLat2 * 0.017453292519943295) / ELLIPSOID.getA()
cosu1 = 1 / math.sqrt(1 + tanu1 * tanu1)
cosu2 = 1 / math.sqrt(1 + tanu2 * tanu2)
sinu1 = tanu1 * cosu1
sinu2 = tanu2 * cosu2
f16 = ELLIPSOID.getF() / 16
lambda1 = (aLon2 - aLon1) * 0.017453292519943295
omega = lambda1
i = 0
sinsigma=0
cossigma=0
sigma=0
cos2alpha=0
cos_twosigma_m=0
while (i < 4):
sinlambda = math.sin( lambda1 )
coslambda = math.cos( lambda1 )
a1 = cosu2 * sinlambda
a2 = cosu1 * sinu2 - sinu1 * cosu2 * coslambda
sinsigma = math.sqrt(a1 * a1 + a2 * a2)
cossigma = sinu1 * sinu2 + cosu1 * cosu2 * coslambda
sigma = math.atan2(sinsigma, cossigma)
sinalpha = cosu1 * cosu2 * sinlambda / sinsigma
cos2alpha = 1 - sinalpha * sinalpha
if cos2alpha < 1.0E-14:
cos_twosigma_m = 0
else :
cos_twosigma_m = cossigma - 2 * sinu1 * sinu2 / cos2alpha
C = f16 * cos2alpha * (4 + ELLIPSOID.getF() * (4 - 3 * cos2alpha))
lambda_old = lambda1
a1 = cos_twosigma_m + C * cossigma * (-1 + 2 * cos_twosigma_m * cos_twosigma_m)
a2 = (1 - C) * ELLIPSOID.getF() * sinalpha * (sigma + C * sinsigma * a1)
lambda1 = omega + a2
if (abs( lambda1 - lambda_old) < 1.0E-10) :
break
i+=1
up2 = cos2alpha * ELLIPSOID.getEMinor2()
aa = 1 + up2 / 16384 * (4096 + up2 * (-768 + up2 * (320 - 175 * up2)))
bb = up2 / 1024 * (256 + up2 * (-128 + up2 * (74 - 47 * up2)))
a1 = cossigma * (-1 + 2 * cos_twosigma_m * cos_twosigma_m)
a2 = cos_twosigma_m * (-3 + 4 * sinsigma * sinsigma)* (-3 + 4 * cos_twosigma_m * cos_twosigma_m);
delta_sigma = bb * sinsigma * (cos_twosigma_m + bb / 4 * (a1 - bb / 6 * a2))
return round(ELLIPSOID.getB() * aa * (sigma - delta_sigma))
def getdist(lon1, lat1, lon2, lat2): # 经纬度算距离
# cc=[114,53,115,53]
# cc=[134,53,135,53]
c1,c2=LonLatPoint(lon1, lat1),LonLatPoint(lon2, lat2)
print("dz==> " , geodesicDistance(c1,c2)) # distance == > 67137
return geodesicDistance(c1,c2)
# getdist(134,53,135,53)
def getlonlat(lon,lat,length,width): # 原经纬度,左右偏上下偏,后的经纬度
if length==width==0:return (lon,lat)
# length = 0
# width = -111195 # 1度纬度固定是111195距离
circleCenter2 = LonLatPoint(lon,lat)
difa=math.degrees(math.atan2(width, length)) # 和上面一样
# print('difa',math.atan2(width, length),difa)
dis_M = math.sqrt(width **2 + length**2)
cal = calPointOnCircle(circleCenter2, dis_M, 90 - difa)
print(cal) # (134.0, 52.0007)
return cal
# getlonlat(134,53, 0, -111195) # 134,52
# getlonlat(90.9,29.3, -50000, 0) # (90.3854, 29.3)
# getlonlat(90.9,29.3, 0, 0) # (90.3854, 29.3)