def extract_nodes( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() pointList = ftools_utils.extractPoints( inGeom ) outFeat.setAttributes( atMap ) for i in pointList: outFeat.setGeometry( outGeom.fromPoint( i ) ) writer.addFeature( outFeat ) del writer return True
def export_geometry(self) : """ Description ----------- Export grid to text file """ gridLayerName = self.listGridLayer.currentText() outTextFileName = self.textOutTextFileName.text() # settings delimiter = ',' lineterminator = '\r' max_decimals = 2 # Error checks if len(outTextFileName) <= 0: return "No output file given" gridLayer = ftools_utils.getMapLayerByName( unicode( gridLayerName ) ) if gridLayer == None: return "Layer " + gridLayerName + " not found" # Create the CSV file try: txtfile = open(outTextFileName, 'w') except ValueError: print "Writing Error. Try again..." # Iterate through each feature in the source layer feature_count = gridLayer.dataProvider().featureCount() # Initialize progress bar progress=QProgressDialog("Exporting attributes...", "Abort Export", 0, feature_count); progress.setWindowModality(Qt.WindowModal) # Select all features along with their attributes allAttrs = gridLayer.pendingAllAttributesList() gridLayer.select(allAttrs) # Iterate over grid cells for feat in gridLayer.getFeatures(): p0, p1, p2, p3 = ftools_utils.extractPoints(feat.geometry())[:4] txtfile.write(str(feat.id()) + ' AUTO' + lineterminator) for point in [p0,p1,p2,p3,p0]: xcoor = round(point.x(), max_decimals) ycoor = round(point.y(), max_decimals) txtfile.write('\t' + str(xcoor) + delimiter + str(ycoor) + lineterminator) txtfile.write('END' + lineterminator) progress.setValue(feat.id()) if (progress.wasCanceled()): return "Export canceled " txtfile.write('END' + lineterminator) progress.close() txtfile.close()
def rect_size(input_feature): """ Description Parameters ---------- input_feature : Qgis vector feature Returns ------- Dictionary {'dx':dx,'dy':dy} where dx and dy are the extents of input_feature. Examples -------- >>> """ # Extract the four corners of input_feature # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints(input_feature.geometry())[:4] # Compute size dx = abs(p1.x() - p0.x()) dy = abs(p3.y() - p0.y()) return( {'dx':dx,'dy':dy} )
def rect_size(input_feature): """ Description Parameters ---------- input_feature : Qgis vector feature Returns ------- Dictionary {'dx':dx,'dy':dy} where dx and dy are the extents of input_feature. Examples -------- >>> """ # Extract the four corners of input_feature # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints(input_feature.geometry())[:4] # Compute size dx = abs(p1.x() - p0.x()) dy = abs(p3.y() - p0.y()) return ({'dx': dx, 'dy': dy})
def compute(self, inName, outName, weightField="", times=1, uniqueField=""): vlayer = ftools_utils.getVectorLayerByName(inName) provider = vlayer.dataProvider() weightIndex = provider.fieldNameIndex(weightField) uniqueIndex = provider.fieldNameIndex(uniqueField) feat = QgsFeature() sRs = provider.crs() check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return if uniqueIndex <> -1: uniqueValues = ftools_utils.getUniqueValues( provider, int(uniqueIndex)) single = False else: uniqueValues = [QVariant(1)] single = True if self.function == 2: fieldList = QgsFields() fieldList.append(QgsField("STD_DIST", QVariant.Double)) fieldList.append(QgsField("UID", QVariant.String)) writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList, QGis.WKBPolygon, sRs) else: fieldList = QgsFields() fieldList.append(QgsField("MEAN_X", QVariant.Double)) fieldList.append(QgsField("MEAN_Y", QVariant.Double)) fieldList.append(QgsField("UID", QVariant.String)) writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList, QGis.WKBPoint, sRs) outfeat = QgsFeature() points = [] weights = [] nFeat = provider.featureCount() * len(uniqueValues) nElement = 0 self.progressBar.setValue(0) self.progressBar.setRange(0, nFeat) for j in uniqueValues: cx = 0.00 cy = 0.00 points = [] weights = [] fit = provider.getFeatures() while fit.nextFeature(feat): nElement += 1 self.progressBar.setValue(nElement) if single: check = j.toString().trimmed() else: check = feat.attributes()[uniqueIndex].toString().trimmed() if check == j.toString().trimmed(): cx = 0.00 cy = 0.00 if weightIndex == -1: weight = 1.00 else: weight = float( feat.attributes()[weightIndex].toDouble()[0]) geom = QgsGeometry(feat.geometry()) geom = ftools_utils.extractPoints(geom) for i in geom: cx += i.x() cy += i.y() points.append(QgsPoint((cx / len(geom)), (cy / len(geom)))) weights.append(weight) sumWeight = sum(weights) cx = 0.00 cy = 0.00 item = 0 for item, i in enumerate(points): cx += i.x() * weights[item] cy += i.y() * weights[item] cx = cx / sumWeight cy = cy / sumWeight meanPoint = QgsPoint(cx, cy) if self.function == 2: values = [] md = 0.00 sd = 0.00 dist = QgsDistanceArea() item = 0 for i in points: tempDist = dist.measureLine(i, meanPoint) values.append(tempDist) item += 1 md += tempDist md = md / item for i in values: sd += (i - md) * (i - md) sd = sqrt(sd / item) outfeat.setGeometry( QgsGeometry.fromPoint(meanPoint).buffer(sd * times, 10)) outfeat.setAttribute(0, QVariant(sd)) outfeat.setAttribute(1, QVariant(j)) else: outfeat.setGeometry(QgsGeometry.fromPoint(meanPoint)) outfeat.setAttribute(0, QVariant(cx)) outfeat.setAttribute(1, QVariant(cy)) outfeat.setAttribute(2, QVariant(j)) writer.addFeature(outfeat) if single: break del writer
def compute(self, inName, outName, weightField="", times=1, uniqueField=""): vlayer = ftools_utils.getVectorLayerByName(inName) provider = vlayer.dataProvider() weightIndex = provider.fieldNameIndex(weightField) uniqueIndex = provider.fieldNameIndex(uniqueField) feat = QgsFeature() allAttrs = provider.attributeIndexes() provider.select(allAttrs) sRs = provider.crs() check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return if uniqueIndex <> -1: uniqueValues = ftools_utils.getUniqueValues(provider, int( uniqueIndex ) ) single = False else: uniqueValues = [QVariant(1)] single = True if self.function == 2: fieldList = { 0 : QgsField("STD_DIST", QVariant.Double), 1 : QgsField("UID", QVariant.String) } writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList, QGis.WKBPolygon, sRs) else: fieldList = { 0 : QgsField("MEAN_X", QVariant.Double), 1 : QgsField("MEAN_Y", QVariant.Double), 2 : QgsField("UID", QVariant.String) } writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList, QGis.WKBPoint, sRs) outfeat = QgsFeature() points = [] weights = [] nFeat = provider.featureCount() * len(uniqueValues) nElement = 0 self.progressBar.setValue(0) self.progressBar.setRange(0, nFeat) for j in uniqueValues: provider.rewind() provider.select(allAttrs) cx = 0.00 cy = 0.00 points = [] weights = [] while provider.nextFeature(feat): nElement += 1 self.progressBar.setValue(nElement) if single: check = j.toString().trimmed() else: check = feat.attributeMap()[uniqueIndex].toString().trimmed() if check == j.toString().trimmed(): cx = 0.00 cy = 0.00 if weightIndex == -1: weight = 1.00 else: weight = float(feat.attributeMap()[weightIndex].toDouble()[0]) geom = QgsGeometry(feat.geometry()) geom = ftools_utils.extractPoints(geom) for i in geom: cx += i.x() cy += i.y() points.append(QgsPoint((cx / len(geom)), (cy / len(geom)))) weights.append(weight) sumWeight = sum(weights) cx = 0.00 cy = 0.00 item = 0 for item, i in enumerate(points): cx += i.x() * weights[item] cy += i.y() * weights[item] cx = cx / sumWeight cy = cy / sumWeight meanPoint = QgsPoint(cx, cy) if self.function == 2: values = [] md = 0.00 sd = 0.00 dist = QgsDistanceArea() item = 0 for i in points: tempDist = dist.measureLine(i, meanPoint) values.append(tempDist) item += 1 md += tempDist md = md / item for i in values: sd += (i-md)*(i-md) sd = sqrt(sd/item) outfeat.setGeometry(QgsGeometry.fromPoint(meanPoint).buffer(sd * times, 10)) outfeat.addAttribute(0, QVariant(sd)) outfeat.addAttribute(1, QVariant(j)) else: outfeat.setGeometry(QgsGeometry.fromPoint(meanPoint)) outfeat.addAttribute(0, QVariant(cx)) outfeat.addAttribute(1, QVariant(cy)) outfeat.addAttribute(2, QVariant(j)) writer.addFeature(outfeat) if single: break del writer
def export_geometry(self): """ Description ----------- Export grid to text file """ gridLayerName = self.listGridLayer.currentText() outTextFileName = self.textOutTextFileName.text() # settings delimiter = ',' lineterminator = '\r' max_decimals = 2 # Error checks if len(outTextFileName) <= 0: return "No output file given" gridLayer = ftools_utils.getMapLayerByName(unicode(gridLayerName)) if gridLayer == None: return "Layer " + gridLayerName + " not found" # Create the CSV file try: txtfile = open(outTextFileName, 'w') except ValueError: print "Writing Error. Try again..." # Iterate through each feature in the source layer feature_count = gridLayer.dataProvider().featureCount() # Initialize progress bar progress = QProgressDialog("Exporting attributes...", "Abort Export", 0, feature_count) progress.setWindowModality(Qt.WindowModal) # Select all features along with their attributes allAttrs = gridLayer.pendingAllAttributesList() gridLayer.select(allAttrs) # Iterate over grid cells for feat in gridLayer.getFeatures(): p0, p1, p2, p3 = ftools_utils.extractPoints(feat.geometry())[:4] txtfile.write(str(feat.id()) + ' AUTO' + lineterminator) for point in [p0, p1, p2, p3, p0]: xcoor = round(point.x(), max_decimals) ycoor = round(point.y(), max_decimals) txtfile.write('\t' + str(xcoor) + delimiter + str(ycoor) + lineterminator) txtfile.write('END' + lineterminator) progress.setValue(feat.id()) if (progress.wasCanceled()): return "Export canceled " txtfile.write('END' + lineterminator) progress.close() txtfile.close()
def get_rgrid_delr_delc(grid_layer): """ Description ---------- get cell dimensions (delr, delc) of a structured (modflow-like) grid layer Parameters ---------- grid_layer: the (modflow-like) structured grid layer Returns ------- (delr, delc) For regular grids, delr and delc are floats For irregular grids, delr and delc are lists Examples -------- >>> delr, delc = get_rgrid_delr_delc(grid_layer) """ # TODO : check if the grid is actually regular # Load layer #allAttrs = grid_layer.pendingAllAttributesList() #grid_layer.select(allAttrs) #grid_layer.dataProvider().select(allAttrs) # Init variables all_features = {feat.id():feat for feat in grid_layer.getFeatures()} allCentroids = [feat.geometry().centroid().asPoint() \ for feat in all_features.values()] centroids_ids = all_features.keys() centroids_x = [centroid.x() for centroid in allCentroids] centroids_y = [centroid.y() for centroid in allCentroids] centroids = np.array( [centroids_ids , centroids_x, centroids_y] ) centroids = centroids.T # get nrow, ncol nrow, ncol = get_rgrid_nrow_ncol(grid_layer) # init list delr = [] delc = [] # sort by decreasing y and increasing x idx_row = np.lexsort([centroids[:,1],-centroids[:,2]]) # iterate along first row for featId in centroids[idx_row,0][:ncol]: # Extract the four corners of feat # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints(all_features[featId].geometry())[:4] delr.append( p1.x() - p0.x() ) # sort by increasing x and decreasing y idx_col = np.lexsort([-centroids[:,2],centroids[:,1]]) # iterate along first col for featId in centroids[idx_col,0][:nrow]: # Extract the four corners of feat # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints(all_features[featId].geometry())[:4] delc.append( p0.y() - p3.y() ) # round delr = [round(val, MAX_DECIMALS) for val in delr] delc = [round(val, MAX_DECIMALS) for val in delc] # If all values are identical, return scalar if delr.count(delr[0]) == len(delr): delr = delr[0] if delc.count(delc[0]) == len(delc): delc = delc[0] return(delr, delc)
def find_neighbors(input_feature, all_features, v_layerIndex): """ Description ---------- Find the neighbors of input_feature and identify the direction Parameters ---------- p1 : parameter 1 Returns ------- out1 : output1 Examples -------- >>> """ # Get neighbors Ids. neighborsId = v_layerIndex.intersects( input_feature.geometry().boundingBox() ) # Get neighbors featNeighbors = [ all_features[featId] for featId in neighborsId ] # Initialize dictionary neighbors = { 'direction':[], 'feature':[] } # Extract the four corners of input_feature # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints(input_feature.geometry())[:4] # Iterate over neighbors for featNeighbor in featNeighbors: # Extract the four corners of neighbor # Note : rectangle points are numbered from top-left to bottom-left, clockwise q0, q1, q2, q3 = ftools_utils.extractPoints(featNeighbor.geometry())[:4] # Numbering rule for neighbors of feature 0 : # | 8 | 1 | 5 | # | 4 | 0 | 2 |/.m # | 7 | 3 | 6 | # Identify type of neighborhood if is_over(p0, q0) and is_over(p1, q1) and is_over(p2, q2) and is_over(p3, q3): cell_dir = 0 # features overlap elif is_over(p0, q3) and is_over(p1, q2): cell_dir = 1 # feature B is above A elif is_over(p1, q0) and is_over(p2, q3): cell_dir = 2 # feature B is to the right of A elif is_over(p2, q1) and is_over(p3, q0): cell_dir = 3 # feature B is below A elif is_over(p3, q2) and is_over(p0, q1): cell_dir = 4 # feature B is to the left of A elif is_over(p1, q3): cell_dir = 5 # feature B is to the top-right corner of A elif is_over(p2, q0): cell_dir = 6 # feature B is to the bottom-right corner of A elif is_over(p3, q1): cell_dir = 7 # feature B is to the bottom-left corner of A elif is_over(p0, q2): cell_dir = 8 # feature B is to the top-left corner of A elif is_colinear( build_vect(q3, p0), build_vect(p1, q2) ) and \ is_colinear(build_vect(q3, p0), {'x':1, 'y':0} ) and \ is_colinear(build_vect(p1, q2), {'x':1, 'y':0} ) : cell_dir = 1 # feature B is above A elif is_colinear( build_vect(q3, p2), build_vect(p1, q0) ) and \ is_colinear(build_vect(q3, p2), {'x':0, 'y':1} ) and \ is_colinear(build_vect(p1, q0), {'x':0, 'y':1} ) : cell_dir = 2 # feature B is to the right of A elif is_colinear( build_vect(q0, p3), build_vect(p2, q1) ) and \ is_colinear(build_vect(q0, p3), {'x':1, 'y':0} ) and \ is_colinear(build_vect(p2, q1), {'x':1, 'y':0} ) : cell_dir = 3 # feature B is below A elif is_colinear( build_vect(q2, p3), build_vect(p0, q1) ) and \ is_colinear(build_vect(q2, p3), {'x':0, 'y':1} ) and \ is_colinear(build_vect(p0, q1), {'x':0, 'y':1} ) : cell_dir = 4 # feature B is to the left of A else : cell_dir = -1 # feature B is not a neighbor in a valid grid # If the feature is an "actual" neighbor, save it to the dictionary # "actual" = neither the feature itself, neither neighbors from corners #if cell_dir > 0 : neighbors['direction'].append(cell_dir) neighbors['feature'].append(featNeighbor) # Return dictionary with neighbors return neighbors
def get_rgrid_delr_delc(grid_layer): """ Description ---------- get cell dimensions (delr, delc) of a structured (modflow-like) grid layer Parameters ---------- grid_layer: the (modflow-like) structured grid layer Returns ------- (delr, delc) For regular grids, delr and delc are floats For irregular grids, delr and delc are lists Examples -------- >>> delr, delc = get_rgrid_delr_delc(grid_layer) """ # TODO : check if the grid is actually regular # Load layer #allAttrs = grid_layer.pendingAllAttributesList() #grid_layer.select(allAttrs) #grid_layer.dataProvider().select(allAttrs) # Init variables all_features = {feat.id(): feat for feat in grid_layer.getFeatures()} allCentroids = [feat.geometry().centroid().asPoint() \ for feat in all_features.values()] centroids_ids = all_features.keys() centroids_x = [centroid.x() for centroid in allCentroids] centroids_y = [centroid.y() for centroid in allCentroids] centroids = np.array([centroids_ids, centroids_x, centroids_y]) centroids = centroids.T # get nrow, ncol nrow, ncol = get_rgrid_nrow_ncol(grid_layer) # init list delr = [] delc = [] # sort by decreasing y and increasing x idx_row = np.lexsort([centroids[:, 1], -centroids[:, 2]]) # iterate along first row for featId in centroids[idx_row, 0][:ncol]: # Extract the four corners of feat # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints( all_features[featId].geometry())[:4] delr.append(p1.x() - p0.x()) # sort by increasing x and decreasing y idx_col = np.lexsort([-centroids[:, 2], centroids[:, 1]]) # iterate along first col for featId in centroids[idx_col, 0][:nrow]: # Extract the four corners of feat # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints( all_features[featId].geometry())[:4] delc.append(p0.y() - p3.y()) # round delr = [round(val, MAX_DECIMALS) for val in delr] delc = [round(val, MAX_DECIMALS) for val in delc] # If all values are identical, return scalar if delr.count(delr[0]) == len(delr): delr = delr[0] if delc.count(delc[0]) == len(delc): delc = delc[0] return (delr, delc)
def find_neighbors(input_feature, all_features, v_layerIndex): """ Description ---------- Find the neighbors of input_feature and identify the direction Parameters ---------- p1 : parameter 1 Returns ------- out1 : output1 Examples -------- >>> """ # Get neighbors Ids. neighborsId = v_layerIndex.intersects( input_feature.geometry().boundingBox()) # Get neighbors featNeighbors = [all_features[featId] for featId in neighborsId] # Initialize dictionary neighbors = {'direction': [], 'feature': []} # Extract the four corners of input_feature # Note : rectangle points are numbered from top-left to bottom-left, clockwise p0, p1, p2, p3 = ftools_utils.extractPoints(input_feature.geometry())[:4] # Iterate over neighbors for featNeighbor in featNeighbors: # Extract the four corners of neighbor # Note : rectangle points are numbered from top-left to bottom-left, clockwise q0, q1, q2, q3 = ftools_utils.extractPoints( featNeighbor.geometry())[:4] # Numbering rule for neighbors of feature 0 : # | 8 | 1 | 5 | # | 4 | 0 | 2 |/.m # | 7 | 3 | 6 | # Identify type of neighborhood if is_over(p0, q0) and is_over(p1, q1) and is_over(p2, q2) and is_over( p3, q3): cell_dir = 0 # features overlap elif is_over(p0, q3) and is_over(p1, q2): cell_dir = 1 # feature B is above A elif is_over(p1, q0) and is_over(p2, q3): cell_dir = 2 # feature B is to the right of A elif is_over(p2, q1) and is_over(p3, q0): cell_dir = 3 # feature B is below A elif is_over(p3, q2) and is_over(p0, q1): cell_dir = 4 # feature B is to the left of A elif is_over(p1, q3): cell_dir = 5 # feature B is to the top-right corner of A elif is_over(p2, q0): cell_dir = 6 # feature B is to the bottom-right corner of A elif is_over(p3, q1): cell_dir = 7 # feature B is to the bottom-left corner of A elif is_over(p0, q2): cell_dir = 8 # feature B is to the top-left corner of A elif is_colinear( build_vect(q3, p0), build_vect(p1, q2) ) and \ is_colinear(build_vect(q3, p0), {'x':1, 'y':0} ) and \ is_colinear(build_vect(p1, q2), {'x':1, 'y':0} ) : cell_dir = 1 # feature B is above A elif is_colinear( build_vect(q3, p2), build_vect(p1, q0) ) and \ is_colinear(build_vect(q3, p2), {'x':0, 'y':1} ) and \ is_colinear(build_vect(p1, q0), {'x':0, 'y':1} ) : cell_dir = 2 # feature B is to the right of A elif is_colinear( build_vect(q0, p3), build_vect(p2, q1) ) and \ is_colinear(build_vect(q0, p3), {'x':1, 'y':0} ) and \ is_colinear(build_vect(p2, q1), {'x':1, 'y':0} ) : cell_dir = 3 # feature B is below A elif is_colinear( build_vect(q2, p3), build_vect(p0, q1) ) and \ is_colinear(build_vect(q2, p3), {'x':0, 'y':1} ) and \ is_colinear(build_vect(p0, q1), {'x':0, 'y':1} ) : cell_dir = 4 # feature B is to the left of A else: cell_dir = -1 # feature B is not a neighbor in a valid grid # If the feature is an "actual" neighbor, save it to the dictionary # "actual" = neither the feature itself, neither neighbors from corners #if cell_dir > 0 : neighbors['direction'].append(cell_dir) neighbors['feature'].append(featNeighbor) # Return dictionary with neighbors return neighbors
def exportBoundaryFile(self): import ftools_utils def LineLength(p1,p2): ll = math.sqrt( (float(p1[0]) - float(p2[0]))**2 + \ (float(p1[1]) - float(p2[1]))**2 ) return(ll) # track # of possible topological errors topoErrorCount = 0 # change to output directory os.chdir(str(self.outDir)) nl = os.linesep # create temporary file names tempsegfile = 'tempsegfile_%s.txt' % os.getpid() tempsortedfile = 'tempsortedfile_%s.txt' % os.getpid() tempadjfile = 'tempadjfile_%s.txt' % os.getpid() tempsortedadjfile = 'tempsortedadjfile_%s.txt' % os.getpid() errorlog = 'topo_error_log_%s.txt' % datetime.date.today().isoformat() # get planning unit layer lname = self.ui.cbxPlanningGrid.currentText() plProv = ftools_utils.getVectorLayerByName(lname).dataProvider() # get feature count fCount = plProv.featureCount() # set tolerance setting if self.ui.cbxTolerance.currentIndex() == 0: # round to 100 tol = -2 elif self.ui.cbxTolerance.currentIndex() == 1: # round to 10 tol = -1 elif self.ui.cbxTolerance.currentIndex() == 3: # round to 0.1 tol = 1 elif self.ui.cbxTolerance.currentIndex() == 4: # round to 0.01 tol = 2 elif self.ui.cbxTolerance.currentIndex() == 5: # round to 0.001 tol = 3 elif self.ui.cbxTolerance.currentIndex() == 6: # round to 0.0001 tol = 4 elif self.ui.cbxTolerance.currentIndex() == 7: # round to 0.00001 tol = 5 else: # round to 1 tol = 0 # set action for cost differences if self.ui.rdoGreatest.isChecked() == True: cAction = 'greatest' elif self.ui.rdoLeast.isChecked() == True: cAction = 'least' else: cAction = 'average' # boundary type if self.ui.rdoLength.isChecked() == True: bType = 'length' elif self.ui.rdoField.isChecked() == True: bType = 'field_value' else: bType = 'lxf' # get field indexes for id and cost fields fidx = plProv.fieldNameIndex(self.ui.cbxIdField.currentText()) if self.ui.rdoLength.isChecked() == True: bcidx = -1 else: bcidx = plProv.fieldNameIndex(self.ui.cbxBoundaryCost.currentText()) # build temporary segment file and dictionary tsf = open(tempsegfile,'w') inGeom = QgsGeometry() feature = QgsFeature() allAttrs = plProv.attributeIndexes() plProv.select(allAttrs) x = 0 segLineCnt = 0 self.ui.lbExportAction.setText('Extracting Segments') while plProv.nextFeature(feature): pid = feature.attributeMap()[fidx].toString() if bcidx != -1: cost = feature.attributeMap()[bcidx].toString() else: cost = '1.0' inGeom = feature.geometry() pointList = ftools_utils.extractPoints(inGeom) prevPoint = 0 for i in pointList: if prevPoint == 0: prevPoint = i else: # write line segment segLen = LineLength([prevPoint[0],prevPoint[1]], [i[0],i[1]]) # make spatial key to segment file if round(float(prevPoint[0]),tol) < round(float(i[0]),tol) or \ (round(float(prevPoint[0]),tol) == round(float(i[0]),tol) \ and round(float(prevPoint[1]),tol) < round(float(i[1]),tol) ): skey = str(round(float(prevPoint[0]),tol)) + '|' + \ str(round(float(prevPoint[1]),tol)) + '|' + \ str(round(float(i[0]),tol)) + '|' + \ str(round(float(i[1]),tol)) else: skey = str(round(float(i[0]),tol)) + '|' + \ str(round(float(i[1]),tol)) + '|' + \ str(round(float(prevPoint[0]),tol)) + '|' + \ str(round(float(prevPoint[1]),tol)) if segLen > 0: tsf.write('%s,%d,%f,%f %s' % \ (skey, int(pid), float(cost), segLen, nl ) ) prevPoint = i # progress update pval = (x*100/3)/fCount/self.exportCount self.progressStatus('update',pval) # increment counter for progress bar x = x + 1 # clean up tsf.close() # notify users self.ui.lbExportAction.setText('Sorting Segments') self.progressStatus('step',pval) pval = (50/3)/self.exportCount self.progressStatus('update',pval) # sort the file batch_sort(tempsegfile, tempsortedfile) os.remove(tempsegfile) # update progress notification self.ui.lbExportAction.setText('Calculating Adjacency') pval = (100/3)/self.exportCount self.progressStatus('step',pval) # loop through sorted file and create adjacency file tsf = open(tempsortedfile,'r') taf = open(tempadjfile,'w') # notify users pval = (40/3)/self.exportCount self.progressStatus('update',pval) done = False pl = '' while not done: line = tsf.readline() if line == '': done = True else: cl = line.rstrip().split(',') if pl != '' and pl != ['']: if cl != '' and pl[0] == cl[0]: fCost = 1 if bType == 'field_value': bCost = 1 if float(pl[2])== float(cl[2]): bCost = float(pl[2]) else: if cAction == 'greatest': bCost = max([float(pl[2]),float(cl[2])]) elif cAction == 'least': bCost = min([float(pl[2]),float(cl[2])]) else: bCost = (float(pl[2]) + float(cl[2]))/2.0 fCost = str(bCost) elif bType == 'lxf': bCost = 1 if float(pl[2])== float(cl[2]): bCost = float(pl[2]) else: if cAction == 'greatest': bCost = max([float(pl[2]),float(cl[2])]) elif cAction == 'least': bCost = min([float(pl[2]),float(cl[2])]) else: bCost = sum([float(pl[2]),float(cl[2])])/2.0 fCost = str(float(pl[3]) * bCost) else: fCost = str(pl[3]) # topology error test # check for more matching lines errorLines = True topologyErrorFound = False pids = '' while errorLines: line = tsf.readline() chkLine = line.rstrip().split(',') if chkLine != '' and chkLine[0] == pl[0]: topologyErrorFound = True # an error exists if pids == '': pids = str(pl[1]) + ',' + str(cl[1]) + ',' + str(chkLine[1]) else: pids = pids + ',' + str(chkLine[1]) else: errorLines = False if topologyErrorFound: if topoErrorCount == 0: el = open(errorlog, 'w') outline = 'There should never be more than 2 overlapping ' + \ 'line segments. ' + nl + \ 'Below are listed cases where more than 2 have ' + \ 'been identified. ' + nl + 'These should all be ' + \ 'corrected before using the boundary file' + nl + \ '-------' + nl el.write(outline) outline = 'Line segments defined as %s may be topologically invalid.%s' % (str(pl[0]),nl) outline = outline + 'Area ids %s appear to overlap.%s--%s' % (pids,nl,nl) el.write(outline) topoErrorCount += 1 else: # no error proceed if int(pl[1]) < int(cl[1]): taf.write('%020d,%020d,%s %s' % (int(pl[1]),int(cl[1]),fCost,nl)) else: taf.write('%020d,%020d,%s %s' % (int(cl[1]),int(pl[1]),fCost,nl)) elif type(pl) == list: fCost = 1 if bType == 'field_value': fCost = str(pl[2]) elif bType == 'lxf': fCost = str(float(pl[3]) * float(pl[2])) else: fCost = str(pl[3]) taf.write('%020d,%020d,%s %s' % (int(pl[1]),int(pl[1]),fCost,nl)) pl = line.rstrip().split(',') tsf.close() taf.close() os.remove(tempsortedfile) # sort adjacency file batch_sort(tempadjfile, tempsortedadjfile) os.remove(tempadjfile) # write boundary file self.ui.lbExportAction.setText('Writing Boundary File') pval = (80/3)/self.exportCount self.progressStatus('update',pval) saf = open(tempsortedadjfile,'r') fname = os.path.join(self.outDir, 'bound.dat') faf = open(fname,'w') faf.write("id1\tid2\tboundary%s" % nl) done = False pl = '' while not done: line = saf.readline() if line == '': done = True cl = '' else: cl = line.rstrip().split(',') if pl != '': if cl != '' and pl[0] == cl[0] and pl[1] == cl[1]: if bType != 'field_value': # note that if field value don't sum the line segments pl = [pl[0],pl[1],sum([float(pl[2]),float(cl[2])])] else: bound = self.adjBound(float(pl[2]),pl[0],pl[1]) if bType in ('field_value','lxf'): boundStr = str(bound) else: boundStr = str(round(float(bound),tol)) if float(bound) > 0.0: faf.write('%d\t%d\t%s%s' % (int(pl[0]),int(pl[1]),boundStr,nl)) pl = line.rstrip().split(',') else: pl = cl saf.close() faf.close() os.remove(tempsortedadjfile) self.ui.lbExportAction.setText('') if topoErrorCount > 0: el.close() warningText = '%d possible topological error(s) found. ' % topoErrorCount warningText = warningText + \ 'Please check error log in same directory as boundary file.' QtGui.QMessageBox.warning(self, self.tr("Export Error"), self.tr(warningText))