def updatePolygonInfo(iface, polygonLayer, polygon_id_field, content_field, parent=None): siteLayer = getLayerByName(u"基站", iface) cellLayer = getLayerByName(u"小区", iface) update_site_dict = {} # 要更新了的基站dict (key: site.id(), value: {field: value}) update_cell_dict = {} # 要更新了的小区dict (key: cell.id(), value: {field: value}) all_polygon = polygonLayer.getFeatures() # 生成进度条 total = polygonLayer.featureCount() progess = Progess(parent, total) progess.show() # 显示进度条 for polygon in all_polygon: polygon_geom = polygon.geometry() polygon_id = polygon[polygon_id_field] if content_field != '': content = polygon[content_field] else: content = None all_site = siteLayer.getFeatures() for site in all_site: if not update_site_dict.has_key(site.id()): site_geom = site.geometry() # 判断是否相交 if site_geom.intersects(polygon_geom): temp_dict = {} temp_dict[site.fieldNameIndex(u'Polygon')] = polygon_id if content != None: temp_dict[site.fieldNameIndex(u'其他')] = content update_site_dict[site.id()] = temp_dict del temp_dict all_cell = cellLayer.getFeatures() for cell in all_cell: if not update_cell_dict.has_key(cell.id()): cell_gemo = cell.geometry() # 判断是否相交 if cell_gemo.intersects(polygon_geom): temp_dict = {} temp_dict[cell.fieldNameIndex(u'Polygon')] = polygon_id if content != None: temp_dict[cell.fieldNameIndex(u'其他')] = content update_cell_dict[cell.id()] = temp_dict del temp_dict progess.count() result1 = modifyFeatures(siteLayer, update_site_dict) result2 = modifyFeatures(cellLayer, update_cell_dict) progess.kill() if result1 and result2: return True else: return False
def delCellFeature(self): if self.__dataprovider.capabilities( ) & QgsVectorDataProvider.DeleteFeatures: delNCells = [] delFeatureIDs = [] modifyNType_dict = {} # 保存要修改 NType 的相邻小区 dict for cell in self.selections: cellId = cell[u'RNC-BSC'] + '_' + (cell[u'基站ID']) + '_' + ( cell[u'小区ID']) delNCells.append(cellId) allNCells = self.scellLayer.getFeatures() for ncell in allNCells: for i in range(len(delNCells)): if ncell['SCell'] == self.SCell and ncell[ 'NCell'] == delNCells[i]: delFeatureIDs.append(ncell.id()) if ncell['SCell'] == delNCells[i] and ncell[ 'NCell'] == self.SCell: if not modifyNType_dict.has_key(ncell.id()): temp_dict = {} temp_dict[ncell.fieldNameIndex('NType')] = 1 modifyNType_dict[ncell.id()] = temp_dict del temp_dict '''检查是否选中了要删除的小区''' if len(delFeatureIDs) == 0: self.iface.messageBar().pushMessage(u'错误', u'请选择要删除的小区', QgsMessageBar.CRITICAL, 3) else: # 先修改NType modifyFeatures(self.scellLayer, modifyNType_dict) # 删除,并返回删除结果 deleteResult = self.__dataprovider.deleteFeatures( delFeatureIDs) return deleteResult else: self.iface.messageBar().pushMessage(u'错误', u'删除相邻小区失败', QgsMessageBar.CRITICAL, 3)
def run(self): allCellFeatures_list = getFeaturesList(self.cellLayer) d = QgsDistanceArea() marco_cells_dict = {} room_cells_dict = {} not_room_cells_list = [] drip_cells_dict = {} PCI_dict = {} # key:cell.id() value:PCI # 先把室分小区筛选出来 for cell in allCellFeatures_list: if cell[u"小区类型"] == u"室分": site_name = cell[u"基站名"] site_id = cell[u"基站ID"] site = (site_id, site_name) if not room_cells_dict.has_key(site): temp_list = [cell] room_cells_dict[site] = temp_list del temp_list else: temp_list = room_cells_dict[site] temp_list.append(cell) room_cells_dict[site] = temp_list del temp_list else: not_room_cells_list.append(cell) # 将非室分的小区按基站来分类以筛选滴灌小区 if not_room_cells_list: cells_dict = {} for cell in not_room_cells_list: site_name = cell[u"基站名"] site_id = cell[u"基站ID"] site = (site_id, site_name) if not cells_dict.has_key(site): temp_list = [cell] cells_dict[site] = temp_list del temp_list else: temp_list = cells_dict[site] temp_list.append(cell) cells_dict[site] = temp_list del temp_list # 筛选宏站和滴灌小区 for (site, cells_list) in cells_dict.iteritems(): if len(cells_list) > 3: drip_cells_dict[site] = cells_list else: marco_cells_dict[site] = cells_list # 生成进度条 progess_len = len(marco_cells_dict)+len(room_cells_dict)+len(drip_cells_dict) progess = Progess(self.parent, progess_len) progess.show() # 先为宏站分配PCI sss = self.marco_range[0] for (site0, cells_list0) in marco_cells_dict.iteritems(): had_used_SSS_set = set() for (site1, cells_list1) in marco_cells_dict.iteritems(): if site0 == site1: continue lon0 = cells_list0[0][u"经度"] lat0 = cells_list0[0][u"纬度"] site_point0 = QgsPoint(lon0, lat0) lon1 = cells_list1[0][u"经度"] lat1 = cells_list1[0][u"纬度"] site_point1 = QgsPoint(lon1, lat1) distance = d.convertMeasurement(d.measureLine(site_point0, site_point1), 2, 0, False)[0] # 单位(米) if distance > 5*self.coverage: continue # 在5倍覆盖范围内 if not PCI_dict.has_key(cells_list1[0].id()): pci1 = cells_list1[0]["PCI"] else: pci1 = PCI_dict[cells_list1[0].id()] if pci1: sss1 = pci1 / 3 had_used_SSS_set.add(sss1) # 为同一基站下的小区分配PCI # 先确定可用SSS for i in range(self.marco_range[0], self.marco_range[1]+1): if sss in had_used_SSS_set: sss = sss + 1 if sss > self.marco_range[1]: sss = self.marco_range[0] else: break cells_list0.sort(key=lambda x:x[u"方向角"]) for index,cell in enumerate(cells_list0): pci = index + 3*sss PCI_dict[cell.id()] = pci progess.count() # 为室分站分配PCI pci_count = self.room_range[0]*3 for (site, cells_list) in room_cells_dict.iteritems(): for cell in cells_list: if pci_count > self.room_range[1]*3 + 2: pci_count = self.room_range[0]*3 PCI_dict[cell.id()] = pci_count pci_count = pci_count + 1 progess.count() # 为滴灌站分配PCI pci_count = self.drip_range[0] * 3 for (site, cells_list) in drip_cells_dict.iteritems(): for cell in cells_list: if pci_count > self.drip_range[1]*3 + 2: pci_count = self.drip_range[0]*3 PCI_dict[cell.id()] = pci_count pci_count = pci_count + 1 progess.count() # 修改图层数据 if PCI_dict: update_dict = {} pci_field_index = self.cellLayer.fieldNameIndex('PCI') for (id, pci) in PCI_dict.iteritems(): update_dict[id] = {pci_field_index:pci} modifyFeatures(self.cellLayer, update_dict) progess.count() return True else: return False
def showCellFeature(self): # 清空元素选择 self.cellLayer.selectAll() self.cellLayer.invertSelection() self.scellLayer.selectAll() self.scellLayer.invertSelection() ncell_dict = self.getNCellList() # 提取所有相邻小区数据 '''变量声明''' showNCellList = [] showNCellIdDict = {} # key 为 NCell, value 为 NType showCellList = [] distanceList = {} t_switchTimes_list = [] s_switchTime_list = [] s_switchRate_list = [] count1 = 0 count2 = 0 '''清空涂色''' if len(self.HL_NCell_O) > 0: for h in self.HL_NCell_O: self.iface.mapCanvas().scene().removeItem(h) if len(self.HL_NCell_D) > 0: for h in self.HL_NCell_D: self.iface.mapCanvas().scene().removeItem(h) '''补全所选中的服务小区的相邻小区信息''' update_dict = {} # 要更新的features dict updateGemo_dict = {} # 要更新的features gemotry dict #featureUtils = FeatureUtils(u'相邻小区', self.iface) allNCells = self.scellLayer.getFeatures() for NCell in allNCells: feature_id = None # 需要更新的相邻小区的features_id if NCell['SCell'] == self.SCell: if NCell.geometry() == None: # 相邻小区的 geometry 不存在才更新信息 feature_id = NCell.id() scell_point = None # 服务小区经纬度 scell_siteId = None # 服务小区所属基站 ncell_point = None # 相邻小区经纬度 ncell_siteId = None # 相邻小区所属基站 allCells = self.cellLayer.getFeatures() for Cell in allCells: if Cell['id'] == NCell['SCell']: scell_point = QgsPoint(Cell[u"经度"], Cell[u"纬度"]) if Cell['id'] == NCell['NCell']: ncell_point = QgsPoint(Cell[u"经度"], Cell[u"纬度"]) if scell_point != None and ncell_point != None: break # 更新相邻小区信息 if feature_id != None and scell_point != None and ncell_point != None: features_value = {} # 需要更新的 features 的值得dict # 判断相邻小区类型 if not ncell_dict.has_key( (NCell['NCell'], NCell['SCell'])): features_value[self.scellLayer.fieldNameIndex( 'NType')] = 1 else: features_value[self.scellLayer.fieldNameIndex( 'NType')] = 2 # 计算距离 d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(scell_point, ncell_point), 2, 0, False)[0] features_value[self.scellLayer.fieldNameIndex( 'Distance')] = distance update_dict[feature_id] = features_value updateGemo_dict[feature_id] = QgsGeometry.fromPolyline( [scell_point, ncell_point]) if len(update_dict) > 0 and len(updateGemo_dict) > 0: modifyFeatures(self.scellLayer, update_dict) modifyFeaturesGeom(self.scellLayer, updateGemo_dict) else: pass '''获得相邻小区表中服务小区的相邻小区id,计算各类型相邻小区的数量,并保存其距离到 distanceList 中''' allNCells = self.scellLayer.getFeatures() for NCell in allNCells: if NCell['SCell'] == self.SCell: # 在相邻小区表中找出 SCell 为所设置的服务小区的项 showNCellIdDict[NCell['NCell']] = NCell['NType'] showNCellList.append(NCell.id()) if NCell['NType'] == '1': count1 = count1 + 1 if NCell['NType'] == '2': count2 = count2 + 1 distanceList[(NCell['SCell'], NCell['NCell'])] = NCell['Distance'] t_switchTimes_list.append(str(NCell['HOAttempt'])) s_switchTime_list.append(str(NCell['HOSucc'])) s_switchRate_list.append(str(NCell['HOSuccRate'])) else: pass '''在小区图层中选中相邻小区,并找到服务小区的名字''' allCells = self.cellLayer.getFeatures() for cell in allCells: for (NCell, NType) in showNCellIdDict.items(): if cell[u'RNC-BSC'] + '_' + (cell[u'基站ID']) + '_' + ( cell[u'小区ID']) == NCell: showCellList.append(cell.id()) # 涂色 self.iface.actionZoomFullExtent().trigger( ) # 涂色前将画布缩放到全图显示 if NType == u"1": # 单向小区涂粉色 h = QgsHighlight(self.iface.mapCanvas(), cell.geometry(), self.cellLayer) h.setFillColor(QColor('Pink')) self.HL_NCell_O.append(h) else: h = QgsHighlight(self.iface.mapCanvas(), cell.geometry(), self.cellLayer) h.setFillColor(QColor('Blue')) self.HL_NCell_D.append(h) if cell[u'RNC-BSC'] + '_' + (cell[u'基站ID']) + '_' + ( cell[u'小区ID']) == self.SCell: scell_name = cell[u'小区名'] '''获得相邻小区的名字,并显示服务小区与相邻小区的距离''' i = 0 allCells = self.cellLayer.getFeatures() info_list = [] for cell2 in allCells: for ncell, distance in distanceList.items(): if ncell[1] == (cell2[u'RNC-BSC'] + '_' + (cell2[u'基站ID']) + '_' + (cell2[u'小区ID'])): ncell_name = cell2[u"小区名"] try: # 显示服务小区与相邻小区的相关信息 info = unicode(scell_name) + u' <----> ' + unicode( ncell_name) + u'之间的距离为: ' + unicode( str(distance)) + u'米' info_list.append(info) i = i + 1 except UnicodeEncodeError: pass '''显示相邻小区''' if len(showCellList) == 0: return False else: self.cellLayer.setSelectedFeatures(showCellList) self.scellLayer.setSelectedFeatures(showNCellList) self.iface.actionZoomToSelected().trigger() self.scellwin = SCellInfoUI(info_list, scell_name, count1, count2) self.scellwin.show() self.scellwin.exec_() return (scell_name, count1, count2)
def addCellFeature2(self): if self.__dataprovider.capabilities( ) & QgsVectorDataProvider.AddFeatures: cellfeatures = [] ncells = {} ncell_dict = self.getNCellList() allCells = self.cellLayer.getFeatures() update_dict = {} # 要更新的features dict updateGemo_dict = {} # 要更新的features gemotry dict '''获得该小区的相邻小区数''' count = {} count = self.countCell(self.SCell, count) '''获得服务小区的SiteId''' scell = self.getCell() scell_SiteId = (scell[u"基站ID"]) scell_point = QgsPoint(scell[u'经度'], scell[u'纬度']) '''添加小区到相邻小区表中''' for ncell in self.selections: ncell_id = ncell[u'RNC-BSC'] + '_' + (ncell[u"基站ID"]) + '_' + ( ncell[u"小区ID"]) ncells[ncell_id] = str(ncell[u"基站ID"]) '''计算ncell的相邻小区个数''' count = self.countCell(ncell_id, count) '''若服务小区与选中的小区重叠,返回 1 ''' if ncell_id == self.SCell: return 1 if not ncell_dict.has_key((self.SCell, ncell_id)): '''若相邻小区表中不存在要添加的相邻小区信息,则添加''' ncell_point = QgsPoint(ncell[u'经度'], ncell[u'纬度']) if (scell_point is not None) and (ncell_point is not None): d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(scell_point, ncell_point), 2, 0, False)[0] cellfaeture = QgsFeature() cellfaeture.initAttributes(8) cellfaeture.setAttribute(0, str(uuid4()).replace( '-', '')) # 生成唯一标识id cellfaeture.setAttribute(1, self.SCell) cellfaeture.setAttribute(2, ncell_id) # 把 NType 置为 2 (双向) cellfaeture.setAttribute(3, '2') if distance >= 0 and (distance is not None): cellfaeture.setAttribute(7, distance) cellfaeture.setGeometry( QgsGeometry.fromPolyline( [scell_point, ncell_point])) cellfeatures.append(cellfaeture) if count.has_key(self.SCell): count[self.SCell] = count[self.SCell] + 1 else: count[self.SCell] = 1 else: # 若已存在则更新信息 update_data_id = ncell_dict[(self.SCell, ncell_id)] update_data_value = {} # 需要更新的 features 的值得dict # 计算距离 ncell_point = QgsPoint(ncell[u'经度'], ncell[u'纬度']) if (scell_point is not None) and (ncell_point is not None): d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(scell_point, ncell_point), 2, 0, False)[0] update_data_value[self.scellLayer.fieldNameIndex( 'Distance')] = distance # NType 设为 2(双向) update_data_value[self.scellLayer.fieldNameIndex( 'NType')] = 2 update_dict[update_data_id] = update_data_value updateGemo_dict[update_data_id] = QgsGeometry.fromPolyline( [scell_point, ncell_point]) '''判断原先是否存在对称相邻小区''' if not ncell_dict.has_key((ncell_id, self.SCell)): # 如果不存在则添加对称相邻小区信息 ncell_point = QgsPoint(ncell[u'经度'], ncell[u'纬度']) if (scell_point is not None) and (ncell_point is not None): d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(ncell_point, scell_point), 2, 0, False)[0] cellfaeture = QgsFeature() cellfaeture.initAttributes(8) cellfaeture.setAttribute(0, str(uuid4()).replace( '-', '')) # 生成唯一标识id cellfaeture.setAttribute(1, ncell_id) cellfaeture.setAttribute(2, self.SCell) # NType 置为 2 (双向) cellfaeture.setAttribute(3, '2') if distance >= 0 and (distance is not None): cellfaeture.setAttribute(7, distance) cellfaeture.setGeometry( QgsGeometry.fromPolyline( [ncell_point, scell_point])) cellfeatures.append(cellfaeture) '''再次计算服务小区的相邻小区数''' if count.has_key(ncell_id): count[ncell_id] = count[ncell_id] + 1 else: count[ncell_id] = 1 else: # 若已存在则对称小区的更新信息 # 把要更新的对称小区的 NType 信息加入到 update_dict 中 update_data_id = ncell_dict[(ncell_id, self.SCell)] update_data_value = {} # 需要更新的 features 的值得dict # 计算距离 ncell_point = QgsPoint(ncell[u'经度'], ncell[u'纬度']) if (scell_point is not None) and (ncell_point is not None): d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(scell_point, ncell_point), 2, 0, False)[0] update_data_value[self.scellLayer.fieldNameIndex( 'Distance')] = distance # NType 设为 2 (双向) update_data_value[self.scellLayer.fieldNameIndex( 'NType')] = 2 update_dict[update_data_id] = update_data_value '''若服务小区的相邻小区数大于31则不添加,并返回 2 ''' if count[self.SCell] > 31: return 2 if count[ncell_id] > 31: return 3 '''添加''' self.__dataprovider.addFeatures(cellfeatures) # 更新相邻小区表内数据 if len(update_dict) > 0: modifyFeatures(self.scellLayer, update_dict) if len(updateGemo_dict) > 0: modifyFeaturesGeom(self.scellLayer, updateGemo_dict) return 0
def addCellFeature1(self): if self.__dataprovider.capabilities( ) & QgsVectorDataProvider.AddFeatures: cellfeatures = [] ncells = {} ncell_dict = self.getNCellList() allCells = self.cellLayer.getFeatures() update_dict = {} # 要更新的features dict updateGemo_dict = {} # 要更新的features gemotry dict '''获得该小区的相邻小区数''' count = {} count = self.countCell(self.SCell, count) '''获得服务小区的基站ID''' scell = self.getCell() scell_SiteId = (scell[u'基站ID']) scell_point = QgsPoint(scell[u"经度"], scell[u"纬度"]) '''添加小区到相邻小区表中''' for ncell in self.selections: ncell_id = ncell[u'RNC-BSC'] + '_' + (ncell[u'基站ID']) + '_' + ( ncell[u'小区ID']) ncells[ncell_id] = str(ncell[u'基站ID']) '''若服务小区与选中的小区重叠,返回 1 ''' if ncell_id == self.SCell: return 1 '''检查相邻小区表中是否已存在要添加的相邻小区信息,若否则添加''' if not ncell_dict.has_key((self.SCell, ncell_id)): ncell_point = QgsPoint(ncell[u"经度"], ncell[u"纬度"]) if (scell_point is not None) and (ncell_point is not None): d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(scell_point, ncell_point), 2, 0, False)[0] cellfaeture = QgsFeature() cellfaeture.initAttributes(8) cellfaeture.setAttribute(0, str(uuid4()).replace( '-', '')) # 生成唯一标识id cellfaeture.setAttribute(1, self.SCell) cellfaeture.setAttribute(2, ncell_id) # 判断是否存在对称相邻小区 if ncell_dict.has_key((ncell_id, self.SCell)): # 如果存在对称小区,则新添加的小区为双向邻区 cellfaeture.setAttribute(3, '2') # 把要更新的对称小区的 NType 信息加入到 update_dict 中 update_data_id = ncell_dict[(ncell_id, self.SCell)] update_data_value = { self.scellLayer.fieldNameIndex('NType'): 2 } update_dict[update_data_id] = update_data_value else: # 如是单向相邻小区 NType 置为 1 cellfaeture.setAttribute(3, '1') if distance >= 0 and (distance is not None): cellfaeture.setAttribute(7, distance) cellfaeture.setGeometry( QgsGeometry.fromPolyline( [scell_point, ncell_point])) cellfeatures.append(cellfaeture) '''再次计算服务小区的相邻小区数''' if count.has_key(self.SCell): count[self.SCell] = count[self.SCell] + 1 else: count[self.SCell] = 1 else: # 若已存在则更新信息 update_data_id = ncell_dict[(self.SCell, ncell_id)] update_data_value = {} # 需要更新的 features 的值得dict # 计算距离 ncell_point = QgsPoint(ncell[u"经度"], ncell[u"纬度"]) if (scell_point is not None) and (ncell_point is not None): d = QgsDistanceArea() distance = d.convertMeasurement( d.measureLine(scell_point, ncell_point), 2, 0, False)[0] update_data_value[self.scellLayer.fieldNameIndex( 'Distance')] = distance # 判断是否存在对称相邻小区 if ncell_dict.has_key((ncell_id, self.SCell)): # 若存在对称小区则 NType 设为 2 update_data_value[self.scellLayer.fieldNameIndex( 'NType')] = 2 else: # 反之,NType 设为 1 update_data_value[self.scellLayer.fieldNameIndex( 'NType')] = 1 update_dict[update_data_id] = update_data_value updateGemo_dict[update_data_id] = QgsGeometry.fromPolyline( [scell_point, ncell_point]) '''若服务小区的相邻小区数大于31则不添加,并返回 2 ''' if count[self.SCell] > 31: return 2 '''添加''' self.__dataprovider.addFeatures(cellfeatures) # 更新相邻小区表内数据 if len(update_dict) > 0: modifyFeatures(self.scellLayer, update_dict) if len(updateGemo_dict) > 0: modifyFeaturesGeom(self.scellLayer, updateGemo_dict) return 0 else: # 图层不能够添加新的Feature,提示错误消息给用户 self.iface.messageBar().pushMessage(u'错误', u'添加相邻小区失败', QgsMessageBar.CRITICAL, 3)