Example #1
0
 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
Example #2
0
 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()
Example #4
0
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} )
Example #5
0
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})
Example #6
0
 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
Example #7
0
 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
Example #8
0
    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()
Example #9
0
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)
Example #10
0
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
Example #11
0
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)
Example #12
0
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
Example #13
0
    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))