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 = Scene.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): # 将region字符串 转化成Region对象 region = mymap.Region(fmt_str=record['region']) # 储存的是格式化后的json字符串 record['region'] = region.to_json() form = SceneForm(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值 scenes_exist = Scene.objects.all() maxid_exist = scenes_exist.aggregate( models.Max('id'))['id__max'] maxid_exist = maxid_exist if maxid_exist else 1 # 给新增的scene添加id id_new = maxid_exist + 1 sceneid_list = [] for scene in object_list: scene.id = id_new sceneid_list.append(scene.id) id_new += 1 Scene.objects.bulk_create(object_list) _workspace.save() # scene_models.check_scenes.delay(sceneid_list) return result
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
def get_map_data(self, request, workspace_name, scene_name): result = { 'errmsg': [], 'data': {}, } _workspace = WorkSpace.objects.get(workspace_name=workspace_name) _scene = Scene.objects.get(workspace=_workspace, scene_name=scene_name) _region = mymap.Region(_scene.region) result['data']['region'] = _scene.region result['data']['center'] = _region.get_center().to_json() outdoor_sites_nearby = _scene.outdoorsitenearbyscene_set.all() json_outdoor_sites_nearby = [] json_outdoor_cells_nearby = [] for obj in outdoor_sites_nearby: json_outdoor_sites_nearby.append({ 'lng': obj.site.lng, 'lat': obj.site.lat, 'site_name': obj.site.site_name, }) cells = obj.site.cell_set.all() cover_cells = obj.outdoorcellcoverscene_set.all() cover_cells = [i.cell for i in cover_cells] for cell in cells: is_cover = False if cell in cover_cells: is_cover = True json_outdoor_cells_nearby.append({ 'lng': obj.site.lng, 'lat': obj.site.lat, 'azimuth': cell.azimuth, 'is_cover': is_cover, }) result['data']['sites_nearby'] = json_outdoor_sites_nearby result['data']['cells_nearby'] = json_outdoor_cells_nearby return result
def to_query(self): center = mymap.Region(self.region).get_center() return { 'scene_id': self.scene_id, 'scene_name': self.scene_name, 'region': self.region, 'scene_type': self.scene_type, 'center': { 'lng': center.lng, 'lat': center.lat, }, }
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
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
def edit_object(self, request, **kwargs): result = { 'errmsg': [], } # 在request.POST中, data数据是修改前的原数据 data = request.POST.get('data') # data 是json格式数据 data = json.loads(data) unique_cols = Scene.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 obj = Scene.objects.get(**obj_dict) record = copy(request.POST) # 修改为可编辑状态 record._mutable = True # 将region字符串 转化成Region对象 region = mymap.Region(fmt_str=record['region']) # 储存的是格式化后的json字符串 record['region'] = region.to_json() # 更新kwargs record['workspace'] = _workspace # scene_dict['region'] = mymapinfo.to_region(scene_dict['region']) form = SceneForm(instance=obj, data=record) # 判断是否有修改, 如果有修改 可以 获取 form.changed_data if form.has_changed(): if form.is_valid(): obj = form.save(commit=False) obj.workspace = _workspace obj.save() _workspace.save() else: for key, value in form.errors.items(): result['errmsg'].append('{}:{}'.format(key, value)) else: result['errmsg'].append('未作修改') return result
def new_object(self, request, **kwargs): # {[114.553593,38.106179];[114.554685,38.10751];[114.560549,38.105811];[114.560239,38.104365];[114.553593,38.106179];[114.553593,38.106179]} result = { 'errmsg': [], } # 不要在request.POST上直接编辑 先copy一份 record = copy(request.POST) # 修改为可编辑状态 record._mutable = True # 将region字符串 转化成Region对象 region = mymap.Region(fmt_str=record['region']) # 储存的是格式化后的json字符串 record['region'] = region.to_json() form = SceneForm(record) if form.is_valid(): obj = form.save(commit=False) _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