You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
4.2 KiB

import geojson
import numpy as np
import pandas as pd
import sqlalchemy
from django.conf import settings
from django.contrib.gis.geos import GEOSGeometry
from geojson import MultiPolygon
from tqdm import tqdm
from service import models
def raschet_real(df, koefs):
koef_summ = sum(koefs.values())
df['rate'] = df[list(koefs.keys())].apply(lambda x: sum([x[k] * koefs[k] for k in list(koefs.keys())]), axis=1)
df['rate'] = df['rate'] / koef_summ
return df
def raschet(tables, filters, koefs, method):
conn = sqlalchemy.create_engine(settings.DB_URL, connect_args={'options': '-csearch_path=public'})
msk_ao = filters.get('msk_ao')
msk_rayon = filters.get('msk_rayon')
rate_from = filters.get('rate_from', None)
rate_to = filters.get('rate_to', None)
category = filters.get('category', [])
categories = ','.join([f"'{c}'" for c in category])
points_df = None
nets_df = None
for table in tables:
if 'point' in table:
if msk_ao is not None:
query = f"select * from {table} where msk_ao={msk_ao} and category in ({categories});" if len(
categories) > 0 else f"select * from {table} where msk_ao={msk_ao};"
elif msk_rayon is not None:
query = f"select * from {table} where msk_rayon={msk_rayon} and category in ({categories});" if len(
categories) > 0 else f"select * from {table} where msk_rayon={msk_rayon};"
else:
query = f"select * from {table} where category in ({categories});" if len(
categories) > 0 else f"select * from {table};"
points = pd.read_sql(query, conn)
if method == 'rate':
points_df = raschet_real(points, koefs)
if rate_from is not None and rate_to is not None:
points_df = points_df[(points_df['rate'] >= rate_from) & (points_df['rate'] <= rate_to)]
else:
points_df = points[(points['model'] >= rate_from) & (points['model'] <= rate_to)]
if 'net' in table:
if msk_ao is not None:
query = f"select * from {table} where msk_ao={msk_ao};"
elif msk_rayon is not None:
query = f"select * from {table} where msk_rayon={msk_rayon};"
else:
query = f"select * from {table};"
nets = pd.read_sql(query, conn)
if method == 'rate':
nets_df = raschet_real(nets, koefs)
if rate_from is not None and rate_to is not None:
nets_df = nets_df[(nets_df['rate'] >= rate_from) & (nets_df['rate'] <= rate_to)]
else:
nets_df = nets[(nets['model'] >= rate_from) & (nets['model'] <= rate_to)]
return points_df, nets_df
# ==============
def load_data(filepath: str):
models.PlacementPoint.objects.all().delete()
df = pd.read_csv(filepath)
df = df.replace(np.nan, None)
df = df.replace('NaT', None)
for row in tqdm(df.to_dict('records'), desc='Loading data...'):
data = {k: row[k] for k in row.keys() if k not in ['id', 'okrug', 'rayon', 'age_month']}
data['location_id'] = row['id']
data['okrug'] = models.AO.objects.get(name=row['okrug'])
data['rayon'] = models.Rayon.objects.get(name=row['rayon'])
models.PlacementPoint.objects.create(**data)
def load_ao_and_rayons(ao_filepath: str,
rayons_filepath: str):
models.AO.objects.all().delete()
models.Rayon.objects.all().delete()
gj = geojson.load(ao_filepath)
objs = gj['features']
for obj in tqdm(objs, desc='Loading AOs...'):
name = obj['properties']['okrug']
coords = obj['geometry']['coordinates']
models.AO.objects.create(**{'name': name, 'polygon': GEOSGeometry(str(MultiPolygon(coords)))})
gj = geojson.load(rayons_filepath)
objs = gj['features']
for obj in tqdm(objs, desc='Loading Rayons...'):
name = obj['properties']['rayon']
coords = obj['geometry']['coordinates']
okr = obj['properties']['okrug']
ao = models.AO.objects.get(name=okr)
models.Rayon.objects.create(**{'name': name, 'polygon': GEOSGeometry(str(MultiPolygon(coords))), 'AO': ao})
print('AO and Rayons loaded')