Exemple #1
0
def get_sites_nearby_scene(_scene, queryset_sites):
    result = []
    _workspace = _scene.workspace
    _region = mymap.Region(_scene.region)
    _center = _region.get_center()
    queryset_sites = queryset_sites.filter(site_type='outdoor')
    for _site in queryset_sites:
        _point = mymap.Point(_site.lng, _site.lat)
        # 宏站按距离进行判断
        delta_lng = abs(_point.lng - _center.lng)
        delta_lat = abs(_point.lat - _center.lat)
        if delta_lng > 0.13 or delta_lat > 0.1:
            # 0.13/0.1 大约代表 22公里左右的限制
            continue
        else:
            # 得到的时包含最小距离和最大距离的tuple
            dis_boder = _point.distance(_region)
            if dis_boder[0] < DISTANCE_NEAR:
                dis_center = _point.distance(_center)
                is_in = _point.in_region(_region)
                result.append(
                    OutdoorSiteNearbyScene(
                        workspace=_workspace,
                        scene=_scene,
                        site=_site,
                        distance_to_center=dis_center,
                        distance_to_border_near=dis_boder[0],
                        distance_to_border_far=dis_boder[1],
                        in_scene=is_in,
                    ))
    return result
Exemple #2
0
def get_scene_cover_sites(scene, sites_nearby_scene):
    _sites_nearby_scene = []
    for item in sites_nearby_scene:
        if not item.in_scene:
            _sites_nearby_scene.append(item)
    if len(_sites_nearby_scene) == 1:
        _sites_nearby_scene[0].cover_order = 1
    else:
        region = mymap.Region(scene.region)
        center = region.get_center()
        ordered_sites_near_reg = sorted(
            _sites_nearby_scene, key=lambda e: e.distance_to_border_near)
        # 以最近的站点的方向为基准方向
        site1 = ordered_sites_near_reg[0].site
        ordered_sites_near_reg[0].cover_order = 1
        p1 = mymap.Point(site1.lng, site1.lat)
        ordered_sites_near_reg[0].azimuth = int(p1.azimuth(center))
        azimuth1 = center.azimuth(p1)
        azimuth2 = 0
        i = 1
        while i < len(ordered_sites_near_reg):
            # 计算当前的站址 和 中心点 角度
            _site = ordered_sites_near_reg[i].site
            _p = mymap.Point(_site.lng, _site.lat)
            _azimuth = center.azimuth(_p)
            if abs(_azimuth - azimuth1) < 90:
                i += 1
                continue
            azimuth2 = _azimuth
            ordered_sites_near_reg[i].cover_order = 2
            ordered_sites_near_reg[i].azimuth = int(_p.azimuth(center))
            break
        i += 1
        while i < len(ordered_sites_near_reg):
            _site = ordered_sites_near_reg[i].site
            _p = mymap.Point(_site.lng, _site.lat)
            _azimuth = center.azimuth(_p)
            if abs(_azimuth - azimuth1) < 90 or abs(_azimuth - azimuth2) < 90:
                i += 1
                continue
            ordered_sites_near_reg[i].cover_order = 3
            ordered_sites_near_reg[i].azimuth = int(_p.azimuth(center))
            break
Exemple #3
0
def get_indoor_sites_in_scene(_scene, queryset_sites):
    result = []
    _workspace = _scene.workspace
    _region = mymap.Region(_scene.region)
    queryset_sites = queryset_sites.filter(site_type="indoor")
    for _site in queryset_sites:
        _point = mymap.Point(_site.lng, _site.lat)
        if _point.in_region(_region):
            result.append(
                IndoorSiteInScene(
                    workspace=_workspace,
                    site=_site,
                    scene=_scene,
                ))
    return result
Exemple #4
0
 def __init__(self, fmt_str):
     # 可以接收 json_str 或者 单引号的类似json_str结构
     # 也可以接收  {[,]; 连接的经纬度
     if "'" in fmt_str:
         fmt_str = fmt_str.replace("'", '"')
     try:
         reg_dict = json.loads(fmt_str)
     except ValueError:
         # 去掉全部的 {} 和 []
         points = fmt_str.replace('{', '').replace('}', '').replace(
             '[', '').replace(']', '')
         # 每对经纬度之间时以;间隔的
         points = points.split(';')
         # 经度和纬度间以,分割
         points = (s.split(',') for s in points)
         points = [mymap.Point(*_l) for _l in points]
     else:
         if 'ends' in reg_dict.keys():
             points = [mymap.Point(**p) for p in reg_dict['ends']]
         else:
             raise ValueError("输入参数中应包含'ends'")
     # 去掉points中相邻的重复点位
     temp_point = None
     list_point = []
     for point in points:
         if point != temp_point:
             temp_point = point
             list_point.append(point)
     # 闭合区域的第一个点和最后一个点应该相同, 为计算方便,默认去掉在ends里不包含最后一个重复的点
     # 如果第一个点和最后一点个相同, 则去除
     if list_point[0] == list_point[-1]:
         list_point = list_point[0:-1]
     if len(list_point) < 3:
         raise ValueError('一个闭合区域区域至少要包含3个不重合的经纬度点')
     # 如果使用生成器,只能遍历一次,转化成tuple对象就不再有此限制
     self.ends = tuple(_p for _p in list_point)
Exemple #5
0
 def new_object(self, request, **kwargs):
     result = {
         'errmsg': [],
     }
     form = SiteForm(request.POST)
     if form.is_valid():
         obj = form.save(commit=False)
         # 格式化经纬度精度
         _point = mymap.Point(obj.lng, obj.lat)
         obj.lng = _point.lng
         obj.lat = _point.lat
         _workspace = WorkSpace.objects.get(**kwargs)
         obj.workspace = _workspace
         obj.save()
         _workspace.save()
     else:
         for key, value in form.errors.items():
             result['errmsg'].append('{}:{}'.format(key, value))
     return result
Exemple #6
0
 def edit_object(self, request, **kwargs):
     result = {
         'errmsg': [],
     }
     # 在request.POST中, data数据是修改前的原数据
     data = request.POST.get('data')
     # data 是json格式数据
     data = json.loads(data)
     unique_cols = Cell.get_unique_fields()
     obj_dict = {
         key: value
         for key, value in data.items() if key in unique_cols
     }
     _workspace = WorkSpace.objects.get(**kwargs)
     obj_dict['workspace'] = _workspace
     # 数据库数据
     _cell = Cell.objects.get(**obj_dict)
     inital_data = _cell.to_dict()
     # 格式化新数据
     record = copy(request.POST)
     # 修改为可编辑状态
     record._mutable = True
     # 格式化数据
     lng = request.POST.get('lng')
     lat = request.POST.get('lat')
     _point = mymap.Point(lng, lat)
     record['lng'] = _point.lng
     record['lat'] = _point.lat
     form = CellForm(instance=_cell, initial=inital_data, data=record)
     if form.has_changed():
         if form.is_valid():
             form.save()
             _workspace.save()
         else:
             for key, value in form.errors.items():
                 result['errmsg'].append('{}:{}'.format(key, value))
     else:
         result['errmsg'].append('未作修改')
     return result
Exemple #7
0
 def new_object(self, request, **kwargs):
     result = {
         'errmsg': [],
     }
     form = CellForm(request.POST)
     if form.is_valid():
         # 格式化经纬度
         _point = mymap.Point(form.cleaned_data['lng'],
                              form.cleaned_data['lat'])
         _workspace = WorkSpace.objects.get(**kwargs)
         _site = None
         try:
             _site = Site.objects.get(workspace=_workspace,
                                      lng=_point.lng,
                                      lat=_point.lat)
         except Site.DoesNotExist:
             site_name = get_site_name(form.cleaned_data['cell_name'])
             _site = Site(
                 workspace=_workspace,
                 site_name=site_name,
                 site_type=form.cleaned_data['cell_type'],
                 lng=_point.lng,
                 lat=_point.lat,
                 is_auto_created=True,
             )
             _site.save()
             _workspace.save()
         finally:
             cell = form.save(commit=False)
             cell.workspace = _workspace
             cell.site = _site
             cell.save()
             _workspace.save()
     else:
         for key, value in form.errors.items():
             result['errmsg'].append('{}:{}'.format(key, value))
     return result
Exemple #8
0
 def upload(self, request, **kwargs):
     result = {
         'errmsg': [],
     }
     _workspace = WorkSpace.objects.get(**kwargs)
     # 获取文件并读取内容
     file = request.FILES.get('file')
     df = myfuncs.read_csv(file)
     # 检查文件头信息  missing_cols 存储缺少的列
     missing_cols = []
     fields = Site.get_upload_fields()
     cols = {field['verbose_name']: field['name'] for field in fields}
     for col in cols.keys():
         if col not in df.columns:
             missing_cols.append(col)
     if missing_cols:
         result['errmsg'].append('导入文件缺少 "{}" 列'.format(
             '、'.join(missing_cols)))
     else:
         # 检查完毕, 表头正常  只需要模板列, 并将列头重命名为内部名
         df = df[cols.keys()]
         df = df.rename(columns=cols)
         # object_list 保存验证正常的 实例
         object_list = []
         # df.to_dict(orient='records') 将DataFrame转化成字典的列表
         for _index, record in enumerate(df.to_dict(orient='records'),
                                         start=1):
             # 格式化 record lng 和 lat
             try:
                 _point = mymap.Point(record['lng'], record['lat'])
             except ValueError as e:
                 result['errmsg'].append(str(e))
             else:
                 record['lng'] = _point.lng
                 record['lat'] = _point.lat
                 # 需要对site_type数据进行处理
                 form = SiteForm(data=record)
                 if form.is_valid():
                     # form.save(commit=False) 保存为Scene对象 但是不存储到数据库
                     obj = form.save(commit=False)
                     obj.workspace = _workspace
                     object_list.append(obj)
                 else:
                     for key in form.errors.keys():
                         # 存在错误的情况, 将错误加入到errmsg
                         result['errmsg'].append('文件第{}行存在错误: {}:{}'.format(
                             _index, key, form.errors[key]))
         if not result['errmsg']:
             # 只有完全不存在errmsg, 才进行批量的存储到数据库的操作
             # 获取当前最大的id值
             sites_exist = Site.objects.all()
             maxid_exist = sites_exist.aggregate(
                 models.Max('id'))['id__max']
             maxid_exist = maxid_exist if maxid_exist else 0
             # 给新增的scene添加id
             id_new = maxid_exist + 1
             siteid_list = []
             for site in object_list:
                 site.id = id_new
                 siteid_list.append(site.id)
                 id_new += 1
             from django.db.utils import IntegrityError
             try:
                 Site.objects.bulk_create(object_list)
                 _workspace.save()
             except IntegrityError:
                 # 存在重合站址
                 not_unique = []
                 # 对object_list 按照lng和lat进行排序
                 sorted_sites = sorted(object_list,
                                       key=lambda x: (x.lng, x.lat),
                                       reverse=False)
                 # 存储对比的临时数据
                 _lng = 0
                 _lat = 0
                 _obj_1 = None
                 for _obj in sorted_sites:
                     if _obj.lng == _lng and _obj.lat == _lat:
                         not_unique.append((_obj_1, _obj))
                     else:
                         _lng = _obj.lng
                         _lat = _obj.lat
                         _obj_1 = _obj
                 if not_unique:
                     result['errmsg'].append('存在{}对重合站址'.format(
                         len(not_unique)))
                     for _item in not_unique:
                         result['errmsg'].append(
                             '{},{},{}和{},{},{}为重合站址'.format(
                                 _item[0].site_name, _item[0].lng,
                                 _item[0].lat, _item[1].site_name,
                                 _item[1].lng, _item[1].lat))
     return result
Exemple #9
0
 def upload(self, request, **kwargs):
     result = {
         'errmsg': [],
     }
     _workspace = WorkSpace.objects.get(**kwargs)
     # 获取文件并读取内容
     file = request.FILES.get('file')
     df = myfuncs.read_csv(file)
     # 检查文件头信息  missing_cols 存储缺少的列
     missing_cols = []
     fields = Cell.get_upload_fields()
     cols = {field['verbose_name']: field['name'] for field in fields}
     for col in cols.keys():
         if col not in df.columns:
             missing_cols.append(col)
     if missing_cols:
         result['errmsg'].append('导入文件缺少 "{}" 列'.format(
             '、'.join(missing_cols)))
     else:
         # 检查完毕, 表头正常  只需要模板列, 并将列头重命名为内部名
         df = df[cols.keys()]
         df = df.rename(columns=cols)
         # 存储cell
         cells = []
         # df.to_dict(orient='records') 将DataFrame转化成字典的列表
         for _index, record in enumerate(df.to_dict(orient='records'),
                                         start=1):
             cell_form = CellForm(data=record)
             if cell_form.is_valid():
                 # 格式化经纬度
                 point = mymap.Point(record['lng'], record['lat'])
                 _site = None
                 try:
                     # 查找已存在的站址数据
                     _site = Site.objects.get(workspace=_workspace,
                                              lng=point.lng,
                                              lat=point.lat)
                 except Site.DoesNotExist:
                     # 如果不存在则需要新建
                     site_name = get_site_name(record['cell_name'])
                     _site = Site(
                         workspace=_workspace,
                         site_type=cell_form.cleaned_data['cell_type'],
                         site_name=site_name,
                         lng=point.lng,
                         lat=point.lat,
                         is_auto_created=True,
                     )
                     _site.save()
                 finally:
                     cell = cell_form.save(commit=False)
                     cell.workspace = _workspace
                     cell.site = _site
                     cells.append(cell)
             else:
                 for key, value in cell_form.errors.items():
                     result['errmsg'].append('{}:{}'.format(key, value))
         if not result['errmsg']:
             # 只有完全不窜在errmsg, 才进行批量的存储到数据库的操作 bulk_create()
             from django.db.utils import IntegrityError
             try:
                 Cell.objects.bulk_create(cells)
                 _workspace.save()
             except IntegrityError as e:
                 # 存在冲突数据
                 result['errmsg'].append(str(e))
     return result
Exemple #10
0
 def get_center(self):
     border = self.get_border()
     return mymap.Point((border['maxlng'] + border['minlng']) / 2,
                        (border['maxlat'] + border['minlat']) / 2)