def get_points(self, pipeline): pipe = [ QgsPointXY(pipeline.vertexAt(i)) for i in range(pipeline.get().childCount()) ] distances = [] breakForce = 0 while True: if breakForce == 1000: break # check isCanceled() to handle cancellation if self.isCanceled(): return False increment = 0 pipeline = QgsGeometry.fromMultiPointXY(pipe) for i in range(len(pipe) - 1): p1 = pipeline.vertexAt(i) p2 = pipeline.vertexAt(i + 1) d = QgsDistanceArea() distance = d.measureLine(QgsPointXY(p1), QgsPointXY(p2)) distances.append(distance) if distance > 10: self.split_line(p1, p2, i + 1 + increment, pipe) increment += 1 breakForce += 1 if distances: if max(distances) <= 10: break distances.clear() return pipeline
def run(self): area_type_dict = {} # (key: area_type, value: nsite index list) d = QgsDistanceArea() # 计算距离 allNSiteFeatures = getFeaturesList(self.nsiteLayer) # 把所有的nsite按区域类型分类 for nsiteFeature in allNSiteFeatures: area_type = nsiteFeature[u"区域类型"] if area_type not in [u"普通市区", u"密集市区", u"农村", u"郊区乡镇"]: area_type = u"普通市区" if not area_type_dict.has_key(area_type): area_type_dict[area_type] = [nsiteFeature] else: t = area_type_dict[area_type] t.append(nsiteFeature) area_type_dict[area_type] = t del t total = len(allNSiteFeatures) # 写进度条 progess = Progess(self.parent, total, u"优化中...") progess.show() delete_list = [] # 要删除的 nsiteFeaures.id() list for (area_type, nsiteFeatures_list) in area_type_dict.items(): if area_type == u"密集市区": mergeDis = 200 elif area_type == u"郊区乡镇": mergeDis = 500 elif area_type == u"农村": mergeDis = 800 else: # 默认普通市区 mergeDis = 300 for nsiteFeatures1 in nsiteFeatures_list: progess.count() lon1 = nsiteFeatures1[u"经度"] lat1 = nsiteFeatures1[u"纬度"] point1 = QgsPoint(float(lon1), float(lat1)) rectangle = createARectangleByCenterPoint(point1, 2000) if nsiteFeatures1.id() in delete_list: progess.count() continue else: request = QgsFeatureRequest() request.setFilterRect(rectangle) for nsiteFeature2 in self.nsiteLayer.getFeatures(request): if nsiteFeatures1.id() == nsiteFeature2.id(): continue if nsiteFeature2.id() in delete_list: continue lon2 = nsiteFeatures1[u"经度"] lat2 = nsiteFeatures1[u"纬度"] point2 = QgsPoint(float(lon2), float(lat2)) distance = d.convertMeasurement( d.measureLine(point1, point2), 2, 0, False)[0] if distance <= mergeDis: delete_list.append(nsiteFeature2.id()) break progess.kill() # 删除features delFeatures(self.nsiteLayer, delete_list) return True
def distance(self): layers = ["POI_Evacu8"] for layer in layers: vl = uf.getLegendLayerByName(self.iface, layer) uf.addFields(vl, ['distance'], [QVariant.Double]) index = vl.fieldNameIndex('distance') feats = vl.getFeatures() dist = QgsDistanceArea() vl.startEditing() for feat in feats: geom = feat.geometry() pt = geom.asPoint() m = dist.measureLine(self.atk_pt, pt) // 1 vl.changeAttributeValue(feat.id(), index, m) vl.commitChanges()
def get_del(self, delete): self.canvas.unsetMapTool(self.emitDel) if delete: layer = "Danger Zones" min_dist = QgsDistanceArea() vl = uf.getLegendLayerByName(self.iface, layer) point = QgsPoint(delete) feats = vl.getFeatures() for feat in feats: geom = feat.geometry() pt = geom.centroid().asPoint() dist = QgsDistanceArea().measureLine(point, pt) if dist < min_dist: min_dist = dist fid = feat.id() vl.startEditing() vl.deleteFeature(fid) vl.commitChanges()
def createdistancearea(self): distancearea = QgsDistanceArea() dest = self.canvas.mapSettings().destinationCrs() distancearea.setSourceCrs(dest, QgsProject.instance().transformContext()) ellispoid = QgsProject.instance().readEntry("Measure", "/Ellipsoid", GEO_NONE) distancearea.setEllipsoid(ellispoid[0]) return distancearea
def select(self, point): layers = ["Buildings to evacuate", "Shelters"] min_dist = QgsDistanceArea() min_layer = QgsVectorLayer() for layer in layers: vl = uf.getLegendLayerByName(self.iface, layer) feats = vl.getFeatures() for feat in feats: geom = feat.geometry() pt = geom.asPoint() dist = QgsDistanceArea().measureLine(point, pt) if dist < min_dist: min_dist = dist min_feat = feat min_id = feat.id() min_layer = vl min_layer.select(min_id) self.canvas.setSelectionColor(QColor("red")) self.canvas.refresh() return min_layer, min_feat
def get_distance(pnt1, pnt2, epsg_code): """ :param pnt1: QgsPoint object :param pnt2: QgsPoint object :returns the distance between pnt1 and pnt2 """ # Create a measure object distance = QgsDistanceArea() crs = QgsCoordinateReferenceSystem() # Sets this CRS by lookup of the given PostGIS SRID in the CRS database. crs.createFromSrid(epsg_code) context = QgsProject.instance().transformContext() distance.setSourceCrs(crs, context) if epsg_code == constants.EPSG_WGS84: distance.setEllipsoid("WGS84") return distance.measureLine(pnt1, pnt2)
def paint(self, p, *args): super(RubberBand, self).paint(p) # p.drawRect(self.boundingRect()) if not roam.config.settings.get("draw_distance", True): return offset = QPointF(5, 5) nodescount = self.numberOfVertices() for index in range(nodescount, -1, -1): if index == 0: return qgspoint = self.getPoint(0, index) qgspointbefore = self.getPoint(0, index - 1) # No point before means we are the first index and there is nothing # before us. if not qgspointbefore: return if qgspoint and qgspointbefore: distance = self.distancearea.measureLine( qgspoint, qgspointbefore) if int(distance) == 0: continue text = QgsDistanceArea.formatDistance(distance, 3, self.unit, keepBaseUnit=False) linegeom = QgsGeometry.fromPolyline( [QgsPoint(qgspoint), QgsPoint(qgspointbefore)]) midpoint = linegeom.centroid().asPoint() midpoint = self.toCanvasCoordinates(midpoint) - self.pos() midpoint += offset path = QPainterPath() path.addText(midpoint, self.font, text) p.setPen(self.blackpen) p.setRenderHints(QPainter.Antialiasing) p.setFont(self.font) p.setBrush(self.whitebrush) p.drawPath(path)
def run(self): d = QgsDistanceArea() self.jlist = self.getNewSites() maxDistance = self.tlist[1] # 最大搜索范围 feature_list = [] existed_name_list = self.getResultNodesNames() for (jindex, jsite) in enumerate(self.jlist): # 遍历结点 perList = [] # 临时列表,用于转化子字典 jnaminDis1, jnaminDis2, jnaminDis3, jnaminDis4, jnaminDis5, jnaminDis6 = [ self.tlist[1] for i in range(6) ] asite1, asite2, asite3, asite4, asite5, asite6 = [ None for i in range(6) ] if jsite[7] == u'农村': minDis = float(self.tlist[2]) elif jsite[7] == u'郊区乡镇': minDis = float(self.tlist[3]) elif jsite[7] == u'密集市区': minDis = float(self.tlist[5]) else: # 区域类型的结点的最小辐射范围 # 默认jsite[7]==u'普通市区' minDis = float(self.tlist[4]) jpoint = jsite.geometry().asPoint() # 先找到结点附近设置搜索范围内的所有基站 area = createARectangleByCenterPoint(jpoint, maxDistance) siteFeatures_list = getFeaturesListByArea(self.siteLayer, area) for asite in siteFeatures_list: # #遍历找到的基站 jnaDis = d.convertMeasurement(d.measureLine(jpoint, \ QgsPoint(asite[4], asite[5])), 2, 0, False)[0] jnaAngle = math.atan2(asite[5] - jpoint.y(), asite[4] - jpoint.x()) jnaAngle = 90.0 - 180 / math.pi * jnaAngle # 弧度转角度(90-方位角,可转为以正北为0度角) if jnaDis <= jnaminDis1 and 0 < jnaAngle <= 60: jnaminDis1 = float('%0.4f' % jnaDis) # 保留四位小数 asite1 = asite elif jnaDis <= jnaminDis2 and 60 < jnaAngle <= 120: jnaminDis2 = float('%0.4f' % jnaDis) # 保留四位小数 asite2 = asite elif jnaDis <= jnaminDis3 and 120 < jnaAngle <= 180: jnaminDis3 = float('%0.4f' % jnaDis) # 保留四位小数 asite3 = asite elif jnaDis <= jnaminDis4 and -180 < jnaAngle <= -120: jnaminDis4 = float('%0.4f' % jnaDis) # 保留四位小数 asite4 = asite elif jnaDis <= jnaminDis5 and -120 < jnaAngle <= -60: jnaminDis5 = float('%0.4f' % jnaDis) # 保留四位小数 asite5 = asite elif jnaDis <= jnaminDis6 and -60 < jnaAngle <= 0: jnaminDis6 = float('%0.4f' % jnaDis) # 保留四位小数 asite6 = asite if jnaminDis1 and asite1: perList.append([jnaminDis1, asite1]) if jnaminDis2 and asite2: perList.append([jnaminDis2, asite2]) if jnaminDis3 and asite3: perList.append([jnaminDis3, asite3]) if jnaminDis4 and asite4: perList.append([jnaminDis4, asite4]) if jnaminDis5 and asite5: perList.append([jnaminDis5, asite5]) if jnaminDis6 and asite6: perList.append([jnaminDis6, asite6]) # 判断是否至少找到一个符合的基站 if len(perList) < 6: for i in range(6 - len(perList)): perList.append(None) # 若数量不足,给列表补None值 NewSiteName = "0" while True: if NewSiteName in existed_name_list: NewSiteName = str(int(NewSiteName) + 1) else: existed_name_list.append(NewSiteName) break tempList1 = [ NewSiteName, str(jpoint.x()), str(jpoint.y()), jsite[7] ] tempList2 = [] tolDistance = 0 suit_site_dict = { } # 用于记录符合基站的基站名和距离 (key: SiteName, value: distance) for L in perList: if isinstance(L, list): # 判断是否为列表类型 tolDistance = tolDistance + L[0] psite = L[1] tempList2.append(psite[2]) # 基站名 tempList2.append(str(L[0])) # 距离 tempList2.append(str(psite[4])) # 经度 tempList2.append(str(psite[5])) # 纬度 suit_site_dict[psite[2]] = L[0] else: tempList2.append('NULL') tempList2.append('NULL') # 没有基站,设为None值 tempList2.append('NULL') tempList2.append('NULL') if ((tolDistance != 0) and (len(suit_site_dict) != 0)): avgDistance = ("%.4f" % (tolDistance / len(suit_site_dict))) # 将符合要求的站点按距离从小到大排序 sorted_list = sorted(suit_site_dict.iteritems(), key=lambda d: d[1], reverse=False) # tempList1后追加最近基站名称,最近基站距离,平均距离 tempList1.extend([ sorted_list[0][0], str(sorted_list[0][1]), str(avgDistance) ]) else: # tempList1后追加最近基站名称,最近基站距离,平均距离 tempList1.extend(["NULL", "NULL", "0"]) NewSite_datas = (tempList1 + tempList2) feature_list.append(createABasicPointFeature( jpoint, NewSite_datas)) if importFeaturesToLayer(self.nsiteLayer, feature_list): self.iface.actionDraw().trigger() return True else: return False
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)
def run(self): totalDict = {} # 用于保存所有基站的计算结果 suit_jlist = {} # 保存符合条件的结点 d = QgsDistanceArea() total = len(self.jlist) #写进度条 progess = Progess(self.parent,total, u"分析中...") progess.show() maxDistance = self.tlist[1] for (jindex, jsite) in enumerate(self.jlist): #遍历结点 perList = [] #临时列表,用于转化子字典 SuitOrNot = True # 结点是否符合标准标志(默认为True符合) jnaDis = None # 保存结点和基站之间的距离 jnaAngle = None jnaminDis1,jnaminDis2,jnaminDis3,jnaminDis4,jnaminDis5,jnaminDis6=[self.tlist[1] for i in range(6)] asite1,asite2,asite3,asite4,asite5,asite6=[None for i in range(6)] if jsite[7]==u'农村': minDis=float(self.tlist[2]) elif jsite[7]==u'郊区乡镇' : minDis=float(self.tlist[3]) elif jsite[7]==u'密集市区' : minDis=float(self.tlist[5]) else: #区域类型的结点的最小辐射范围 # 默认jsite[7]==u'普通市区' minDis=float(self.tlist[4]) jpoint=jsite.geometry().asPoint() # 先找到结点附近设置搜索范围内的所有基站 area = createARectangleByCenterPoint(jpoint, maxDistance) siteFeatures_list = getFeaturesListByArea(self.siteLayer, area) for asite in siteFeatures_list: #遍历找到的基站 jnaDis = d.convertMeasurement(d.measureLine(jpoint,\ QgsPoint(asite[4], asite[5])), 2, 0, False)[0] if jnaDis < minDis: # 如果存在一个基站与结点间距离小于所设定的范围,则忽略该结点 SuitOrNot = False break jnaAngle = math.atan2(asite[5]-jpoint.y(), asite[4]-jpoint.x()) jnaAngle =90.0 - 180 / math.pi * jnaAngle #弧度转角度(90-方位角,可转为以正北为0度角) if jnaDis <= jnaminDis1 and 0 < jnaAngle <= 60 : jnaminDis1 = float('%0.4f' % jnaDis) # 保留四位小数 asite1 = asite elif jnaDis <= jnaminDis2 and 60 < jnaAngle <= 120 : jnaminDis2 = float('%0.4f' % jnaDis) # 保留四位小数 asite2 = asite elif jnaDis <= jnaminDis3 and 120 < jnaAngle <= 180 : jnaminDis3 = float('%0.4f' % jnaDis) # 保留四位小数 asite3 = asite elif jnaDis <= jnaminDis4 and -180 < jnaAngle <= -120 : jnaminDis4 = float('%0.4f' % jnaDis) # 保留四位小数 asite4 = asite elif jnaDis <= jnaminDis5 and -120 < jnaAngle <= -60 : jnaminDis5 = float('%0.4f' % jnaDis) # 保留四位小数 asite5 = asite elif jnaDis <= jnaminDis6 and -60 < jnaAngle <= 0 : jnaminDis6 = float('%0.4f' % jnaDis) # 保留四位小数 asite6 = asite if jnaminDis1 and asite1 : perList.append([jnaminDis1,asite1]) if jnaminDis2 and asite2 : perList.append([jnaminDis2,asite2]) if jnaminDis3 and asite3 : perList.append([jnaminDis3,asite3]) if jnaminDis4 and asite4 : perList.append([jnaminDis4,asite4]) if jnaminDis5 and asite5 : perList.append([jnaminDis5,asite5]) if jnaminDis6 and asite6 : perList.append([jnaminDis6,asite6]) # 判断是否至少找到一个符合的基站 if len(perList) == 0: # 如果一个符合的基站都没有,则判断该节点不符合,跳过此次循环 SuitOrNot = False elif len(perList) < 6 : for i in range(6-len(perList)) : perList.append(None) #若数量不足,给列表补None值 if SuitOrNot == True: # 结点符合才添加 totalDict[jindex] = perList #记录新建基站的计算结果,{0:[[],[],[],……],1:[……],……} suit_jlist[jindex] = jsite progess.count() #进度条+1 self.calculationResult.emit(suit_jlist, totalDict)