示例#1
0
    def postCorrectionDissolve(self, areas, nAreas):
        def deleteAreaFromW(areaId, newId, W):
            neighs = W[areaId]
            W.pop(areaId)
            for n in neighs:
                W[n].remove(areaId)
                if n != newId:
                    W[n].append(newId)
                    W[n] = list(set(W[n]))
            W[newId].extend(neighs)
            W[newId] = list(set(W[newId]))
            W[newId].remove(newId)
            return W

        pos = 0
        Wrook, Wqueen = weightsFromAreas(areas)
        aIds = [x for x in list(Wrook.keys()) if len(Wrook[x]) > 0]
        aIds0 = [x for x in list(Wrook.keys()) if len(Wrook[x]) == 0]
        areas = [areas[x] for x in aIds]
        areas.sort(key=lambda x: len(x[0]))
        Wrook, Wqueen = weightsFromAreas(areas)
        availableAreas = list(Wrook.keys())
        end = False
        pos = availableAreas.pop(0)
        id2pos = list(Wrook.keys())
        while len(areas) > nAreas and not end:
            area = areas[id2pos.index(pos)]
            if len(Wrook[pos]) > 0:
                neighs = Wrook[pos]
                neighs.sort(key=lambda x: areas[id2pos.index(x)].area(),
                            reverse=True)
                for k, nneigh in enumerate(neighs):
                    neigh = areas[id2pos.index(nneigh)]
                    narea = area | neigh
                    if len(narea) == 1:
                        areas[id2pos.index(nneigh)] = narea
                        areas.pop(id2pos.index(pos))
                        id2pos.remove(pos)
                        Wrook = deleteAreaFromW(
                            pos, nneigh, Wrook)  # El error puede estar aca
                        break
                    else:
                        pass
                if len(areas) == nAreas:
                    end = True
                    break
                else:
                    if len(availableAreas) > 0:
                        pos = availableAreas.pop(0)
                    else:
                        end = True
            else:
                Wrook.pop(pos)
                area = areas.pop(id2pos.index(pos))
                id2pos.remove(pos)
                if len(availableAreas) > 0:
                    pos = availableAreas.pop(0)
                else:
                    end = True
        return areas
示例#2
0
 def postCorrectionDissolve(self,areas,nAreas):
     def deleteAreaFromW(areaId,newId,W):
         neighs = W[areaId]
         W.pop(areaId)
         for n in neighs:
             W[n].remove(areaId)
             if n != newId:
                 W[n].append(newId)
                 W[n] = list(set(W[n]))
         W[newId].extend(neighs)
         W[newId] = list(set(W[newId]))
         W[newId].remove(newId)
         return W
     pos = 0
     Wrook, Wqueen = weightsFromAreas(areas)
     aIds = filter(lambda x: len(Wrook[x])>0,Wrook.keys())
     aIds0 = filter(lambda x: len(Wrook[x])==0,Wrook.keys())
     areas = [areas[x] for x in aIds]
     areas.sort(key = lambda x: len(x[0]))
     Wrook, Wqueen = weightsFromAreas(areas)
     availableAreas = Wrook.keys()
     end = False
     pos = availableAreas.pop(0)
     id2pos = Wrook.keys()
     while len(areas) > nAreas and not end:
         area = areas[id2pos.index(pos)]
         if len(Wrook[pos]) > 0:
             neighs = Wrook[pos]
             neighs.sort(key=lambda x: areas[id2pos.index(x)].area(),reverse=True)
             for k,nneigh in enumerate(neighs):
                 neigh = areas[id2pos.index(nneigh)]
                 narea = area | neigh
                 if len(narea) == 1:
                     areas[id2pos.index(nneigh)] = narea
                     areas.pop(id2pos.index(pos))
                     id2pos.remove(pos)
                     Wrook = deleteAreaFromW(pos,nneigh,Wrook) # El error puede estar aca
                     break
                 else:
                     pass
             if len(areas) == nAreas:
                 end = True
                 break
             else:
                 if len(availableAreas) > 0:
                     pos = availableAreas.pop(0)
                 else:
                     end = True
         else:
             Wrook.pop(pos)
             area = areas.pop(id2pos.index(pos))
             id2pos.remove(pos)
             if len(availableAreas) > 0:
                 pos = availableAreas.pop(0)
             else:
                 end = True
     return areas
示例#3
0
def importShape(shapefile):
    """Reads the geographic information stored in a shape file and returns
    them in python objects.
    
    :param shapefile: path to shapefile including the extension ".shp"
    :type shapefile: string
    :rtype: tuple (coordinates(List), Wqueen(Dict), Wrook(Dict)).

    **Example** ::

        import clusterpy
        chinaAreas = clusterpy.importShape("clusterpy/data_examples/china.shp")
    """

    INFO, areas = readShape(shapefile)
    if INFO['type'] == 5:
        Wqueen, Wrook = weightsFromAreas(areas)
        shpType = 'polygon'
    elif INFO['type'] == 3:
        shpType = 'line'
        Wrook = {}
        Wqueen = {}
    elif INFO['type'] == 1:
        shpType = 'point'
        Wrook = {}
        Wqueen = {}
    return areas, Wqueen, Wrook, shpType
示例#4
0
def importShape(shapefile):
    """Reads the geographic information stored in a shape file and returns
    them in python objects.
    
    :param shapefile: path to shapefile including the extension ".shp"
    :type shapefile: string
    :rtype: tuple (coordinates(List), Wqueen(Dict), Wrook(Dict)).

    **Example** ::

        import clusterpy
        chinaAreas = clusterpy.importShape("clusterpy/data_examples/china.shp")
    """

    INFO, areas = readShape(shapefile)
    if INFO['type'] == 5:
        Wqueen, Wrook = weightsFromAreas(areas)
        shpType = 'polygon'
    elif INFO['type'] == 3:
        shpType = 'line'
        Wrook = {}
        Wqueen = {}
    elif INFO['type'] == 1:
        shpType = 'point'
        Wrook = {}
        Wqueen = {}
    return areas, Wqueen, Wrook, shpType
示例#5
0
def rimap(n,
          N=30,
          alpha=[0.01, 0.3],
          sigma=[1.1, 1.4],
          dt=0.1,
          pg=0.01,
          pu=0.05,
          su=0.315,
          boundary=""):
    """Creates an irregular maps

        :param n: number of areas 
        :type n: integer
        :param N: number of points sampled from each irregular polygon (MR-Polygon) 
        :type N: integer
        :param alpha: min and max value to sampled alpha; default is (0.1,0.5)
        :type alpha: List
        :param sigma: min and max value to sampled sigma; default is (1.2,1.5)
        :type sigma: List
        :param dt: time delta to be used to create irregular polygons (MR-Polygons)
        :type dt: Float
        :param pg: parameter to define the scaling factor of each polygon before being introduced as part of the irregular map
        :type pg: Float
        :param pu: parameter to define the probability of increase the number of areas of each polygon before being introduced into the irregular map
        :type pu: Float
        :param su: parameter to define how much is increased the number of areas of each polygon before being introduced into the irregular map
        :type su: Float
        :param boundary: Initial irregular boundary to be used into the recursive irregular map algorithm
        :type boundary: Layer

        :rtype: Layer
        :return: RI-Map instance 

        **Examples** ::

            import clusterpy
            lay = clusterpy.rimap(1000)
            lay.exportArcData("rimap_1000")
    """

    rm = rim(n, N, alpha, sigma, dt, pg, pu, su, boundary)
    areas = rm.carteAreas
    areas = fixIntersections(areas)
    Wqueen, Wrook, = weightsFromAreas(areas)
    layer = Layer()
    layer.areas = areas
    layer.Wqueen = Wqueen
    layer.Wrook = Wrook
    layer.shpType = 'polygon'
    layer.name = "rimap_" + str(len(areas))
    layer.fieldNames = ["Id", "nw"]
    layer.Y = {}
    for i in Wrook:
        layer.Y[i] = [i, len(Wrook[i])]
    return layer
示例#6
0
def rimap(n, N = 30, alpha = [0.01,0.3], sigma = [1.1,1.4], dt = 0.1,
            pg = 0.01, pu = 0.05, su = 0.315, boundary = ""):
    """Creates an irregular maps

        :param n: number of areas 
        :type n: integer
        :param N: number of points sampled from each irregular polygon (MR-Polygon) 
        :type N: integer
        :param alpha: min and max value to sampled alpha; default is (0.1,0.5)
        :type alpha: List
        :param sigma: min and max value to sampled sigma; default is (1.2,1.5)
        :type sigma: List
        :param dt: time delta to be used to create irregular polygons (MR-Polygons)
        :type dt: Float
        :param pg: parameter to define the scaling factor of each polygon before being introduced as part of the irregular map
        :type pg: Float
        :param pu: parameter to define the probability of increase the number of areas of each polygon before being introduced into the irregular map
        :type pu: Float
        :param su: parameter to define how much is increased the number of areas of each polygon before being introduced into the irregular map
        :type su: Float
        :param boundary: Initial irregular boundary to be used into the recursive irregular map algorithm
        :type boundary: Layer

        :rtype: Layer
        :return: RI-Map instance 

        **Examples** ::

            import clusterpy
            lay = clusterpy.rimap(1000)
            lay.exportArcData("rimap_1000")
    """

    rm = rim(n, N, alpha, sigma, dt, pg, pu, su, boundary)
    areas = rm.carteAreas
    areas = fixIntersections(areas)
    Wqueen,Wrook, = weightsFromAreas(areas)
    layer = Layer()
    layer.areas = areas
    layer.Wqueen = Wqueen
    layer.Wrook = Wrook
    layer.shpType = 'polygon'
    layer.name = "rimap_" + str(len(areas))
    layer.fieldNames = ["Id","nw"]
    layer.Y = {}
    for i in Wrook:
        layer.Y[i] = [i,len(Wrook[i])]
    return layer
示例#7
0
def createGrid(nRows, nCols, lowerLeft=None, upperRight=None):
    """Creates a new Layer with a regular lattice
    
    :param nRows: number of rows
    :type nRows: integer
    :param nCols: number of columns
    :type nCols: integer
    :type lowerLeft: tuple or none, lower-left corner coordinates; default is (0,0) 
    :type upperRight: tuple or none, upper-right corner coordinates; default is (100,100)
    :rtype: Layer new lattice 

    **Description**

    Regular lattices are widely used in both theoretical and empirical
    applications in Regional Science. The example below shows how easy 
    the creation of this kind of maps is using clusterPy.
    
    **Examples**

    Create a grid of ten by ten points.::

        import clusterpy
        points = clusterpy.createGrid(10,10)

    Create a grid of ten by ten points on the bounding box (0,0,100,100).::

        import clusterpy
        points = clusterpy.createGrid(10, 10, lowerLeft=(0, 0), upperRight=(100, 100))
    """
    print "Creating grid"
    if lowerLeft != None and upperRight != None:
        ymin = lowerLeft[1]
        ymax = upperRight[1]
        xmin = lowerLeft[0]
        xmax = upperRight[0]
        areaHeight = float(ymax - ymin) / nRows
        areaWidth = float(xmax - xmin) / nCols
    else:
        ymin = 0
        xmin = 0
        xmax = 10 * nCols
        ymax = 10 * nRows
        areaHeight = 10
        areaWidth = 10
    nyPoints = nRows
    nxPoints = nCols
    N = nyPoints * nxPoints
    Y = {}
    acty = ymax
    actx = xmin
    map = []
    wr = {}
    wq = {}
    # Creating the wr matrix writh towrer criterium
    disAreas = [0, nxPoints - 1, (N - nxPoints), N - 1]
    wr[0] = [1, nyPoints]
    wr[nxPoints - 1] = [nxPoints - 2, 2 * nxPoints - 1]
    wr[N - nxPoints] = [N - nxPoints - nxPoints, N - nxPoints + 1]
    wr[N - 1] = [N - 2, N - 1 - nxPoints]
    wq[0] = [1, nxPoints, nxPoints + 1]
    wq[nxPoints -
       1] = [nxPoints - 2, nxPoints + nxPoints - 1, nxPoints + nxPoints - 2]
    wq[N - nxPoints] = [
        N - nxPoints - nxPoints, N - nxPoints + 1, N - nxPoints - nxPoints + 1
    ]
    wq[N - 1] = [N - 2, N - 1 - nxPoints, N - 1 - nxPoints - 1]
    verticalBorderAreas = []
    for i in range(1, nxPoints -
                   1):  #Asigning the neighborhood of the corner Areas
        wr[i * nxPoints] = [
            i * nxPoints - nxPoints, i * nxPoints + 1, i * nxPoints + nxPoints
        ]
        wr[nxPoints * i + nxPoints - 1] = [
            nxPoints * i - 1, nxPoints * i + nxPoints - 2,
            nxPoints * i + 2 * nxPoints - 1
        ]
        wq[i * nxPoints] = [
            i * nxPoints - nxPoints, i * nxPoints - nxPoints + 1,
            i * nxPoints + 1, i * nxPoints + nxPoints,
            i * nxPoints + nxPoints + 1
        ]
        wq[nxPoints * i + nxPoints - 1] = [
            nxPoints * i - 1, nxPoints * i - 2, nxPoints * i + nxPoints - 2,
            nxPoints * i + 2 * nxPoints - 1, nxPoints * i + 2 * nxPoints - 2
        ]
        disAreas = disAreas + [i * nxPoints, nxPoints * i + nxPoints - 1]
    disAreas = disAreas + range(1, nxPoints - 1) + range(
        (N - nxPoints) + 1, N - 1)
    for i in range(1, nxPoints -
                   1):  # Asigning the neighborhood of the side Areas
        wr[i] = [i - 1, i + nxPoints, i + 1]
        wq[i] = [
            i - 1, i + nxPoints - 1, i + nxPoints, i + nxPoints + 1, i + 1
        ]
    for i in range((N - nxPoints) + 1, N - 1):
        wr[i] = [i - 1, i - nxPoints, i + 1]
        wq[i] = [
            i - 1, i - nxPoints - 1, i - nxPoints, i - nxPoints + 1, i + 1
        ]
    cont = 0
    for i in range(nyPoints):  #Creating de clusterPy areas
        nexty = acty - areaHeight
        for j in range(nxPoints):
            nextx = actx + areaWidth
            x1 = tuple([actx, acty])
            x2 = tuple([nextx, acty])
            x3 = tuple([nextx, nexty])
            x4 = tuple([actx, nexty])
            x5 = tuple([actx, acty])
            area = [x1, x2, x3, x4, x5]
            map.append([area])
            actx = nextx
            if cont not in disAreas:  # Asigning the rest of the neighborhoods
                wr[cont] = [
                    cont - 1, cont - nxPoints, cont + 1, cont + nxPoints
                ]
                wq[cont] = [
                    cont - 1, cont - nxPoints - 1, cont - nxPoints,
                    cont - nxPoints + 1, cont + 1, cont + nxPoints - 1,
                    cont + nxPoints, cont + nxPoints + 1
                ]
            cont = cont + 1
        acty = nexty
        actx = xmin
    for i in range(N):
        Y[i] = [i]
    layer = Layer()
    layer.Y = Y
    layer.fieldNames = ['ID']
    layer.areas = map
    layer.Wrook = wr
    layer.Wqueen = wq
    layer.Wqueen, layer.Wrook, = weightsFromAreas(layer.areas)
    layer.shpType = 'polygon'
    layer.name = 'root'
    layer._defBbox()
    print "Done"
    return layer
示例#8
0
def createHexagonalGrid(nRows, nCols, lowerLeft=(0, 0), upperRight=(100, 100)):
    """Creates a new Layer with a hexagonal regular lattice
    
    :param nRows: number of rows
    :type nRows: integer
    :param nCols: number of columns
    :type nCols: integer
    :type lowerLeft: tuple or none, lower-left corner coordinates; default is (0,0) 
    :type upperRight: tuple or none, upper-right corner coordinates; default is (100,100)
    :rtype: Layer new lattice 

    **Description**

    Regular lattices are widely used in both theoretical and empirical
    applications in Regional Science. The example below shows how easy 
    the creation of this kind of maps is using clusterPy.
    
    **Examples**

    Create a grid of ten by ten points.::

        import clusterpy
        points = clusterpy.createGrid(10,10)
    
    Create a grid of ten by ten points on the bounding box (0,0,100,100).::

        import clusterpy
        points = clusterpy.createGrid(10, 10, lowerLeft=(0, 0), upperRight=(100, 100))
    """
    print "Creating grid"
    rowHeight = (upperRight[1] - lowerLeft[1]) / float(nRows)
    colStep = rowHeight / float(2)
    N = nRows * nCols
    areas = []
    for row in range(nRows):
        actx = lowerLeft[0]
        for col in range(nCols):
            if col != 0:
                actx += 2 * colStep
            if col % 2 == 1:
                y0 = lowerLeft[1] + rowHeight * row - 2 * rowHeight / float(2)
                y1 = lowerLeft[1] + rowHeight * row - rowHeight / float(2)
                y2 = lowerLeft[1] + rowHeight * row
            else:
                y0 = lowerLeft[1] + rowHeight * row - rowHeight / float(2)
                y1 = lowerLeft[1] + rowHeight * row
                y2 = lowerLeft[1] + rowHeight * row + rowHeight / float(2)
            x0 = actx
            x1 = actx + colStep
            x2 = actx + 2 * colStep
            x3 = actx + 3 * colStep
            pol = [(x0, y1), (x1, y2), (x2, y2), (x3, y1), (x2, y0), (x1, y0),
                   (x0, y1)]
            areas.append([pol])
    Y = {}
    for i in range(N):
        Y[i] = [i]
    layer = Layer()
    layer.Y = Y
    layer.fieldNames = ['ID']
    layer.areas = areas
    layer.Wqueen, layer.Wrook, = weightsFromAreas(layer.areas)
    layer.shpType = 'polygon'
    layer.name = 'root'
    layer._defBbox()
    print "Done"
    return layer
示例#9
0
def createGrid(nRows, nCols, lowerLeft=None, upperRight=None):
    """Creates a new Layer with a regular lattice
    
    :param nRows: number of rows
    :type nRows: integer
    :param nCols: number of columns
    :type nCols: integer
    :type lowerLeft: tuple or none, lower-left corner coordinates; default is (0,0) 
    :type upperRight: tuple or none, upper-right corner coordinates; default is (100,100)
    :rtype: Layer new lattice 

    **Description**

    Regular lattices are widely used in both theoretical and empirical
    applications in Regional Science. The example below shows how easy 
    the creation of this kind of maps is using clusterPy.
    
    **Examples**

    Create a grid of ten by ten points.::

        import clusterpy
        points = clusterpy.createGrid(10,10)

    Create a grid of ten by ten points on the bounding box (0,0,100,100).::

        import clusterpy
        points = clusterpy.createGrid(10, 10, lowerLeft=(0, 0), upperRight=(100, 100))
    """
    print "Creating grid"
    if lowerLeft != None and upperRight != None:
        ymin = lowerLeft[1]
        ymax = upperRight[1]
        xmin = lowerLeft[0]
        xmax = upperRight[0]
        areaHeight = float(ymax - ymin) / nRows
        areaWidth = float(xmax - xmin) / nCols
    else:
        ymin = 0
        xmin = 0
        xmax = 10*nCols
        ymax = 10*nRows
        areaHeight = 10
        areaWidth = 10
    nyPoints = nRows
    nxPoints = nCols
    N = nyPoints*nxPoints
    Y = {}
    acty = ymax
    actx = xmin
    map = []
    wr = {}
    wq = {}
    # Creating the wr matrix writh towrer criterium
    disAreas = [0, nxPoints - 1, (N-nxPoints), N - 1]
    wr[0] = [1, nyPoints]
    wr[nxPoints - 1] = [nxPoints - 2, 2 * nxPoints - 1]
    wr[N - nxPoints] = [N - nxPoints - nxPoints, N - nxPoints + 1]
    wr[N - 1] = [N - 2, N - 1 - nxPoints]
    wq[0] = [1, nxPoints, nxPoints + 1]
    wq[nxPoints - 1] = [nxPoints - 2, nxPoints + nxPoints - 1,
            nxPoints + nxPoints - 2]
    wq[N - nxPoints] = [N - nxPoints - nxPoints, N - nxPoints + 1,
            N - nxPoints - nxPoints + 1]
    wq[N - 1] = [N - 2, N - 1 - nxPoints, N - 1 - nxPoints - 1]
    verticalBorderAreas = []
    for i in range(1, nxPoints - 1): #Asigning the neighborhood of the corner Areas
        wr[i * nxPoints] = [i * nxPoints - nxPoints, i * nxPoints + 1,
                i * nxPoints + nxPoints]
        wr[nxPoints * i + nxPoints - 1] = [nxPoints * i - 1,
                nxPoints * i + nxPoints - 2, nxPoints * i + 2 * nxPoints - 1]
        wq[i * nxPoints] = [i * nxPoints - nxPoints, i * nxPoints - nxPoints + 1,
                i * nxPoints + 1,i * nxPoints + nxPoints, i * nxPoints + nxPoints + 1]
        wq[nxPoints * i + nxPoints - 1] = [nxPoints * i - 1, nxPoints * i - 2,
                nxPoints * i + nxPoints - 2, nxPoints * i + 2 * nxPoints - 1,
                nxPoints * i + 2 * nxPoints - 2]
        disAreas = disAreas + [i * nxPoints, nxPoints * i + nxPoints - 1]
    disAreas = disAreas + range(1, nxPoints - 1) + range((N - nxPoints) + 1, N - 1)
    for i in range(1, nxPoints - 1): # Asigning the neighborhood of the side Areas
        wr[i]=[i - 1, i + nxPoints, i + 1]
        wq[i]=[i - 1, i + nxPoints - 1, i + nxPoints, i + nxPoints + 1, i + 1]
    for i in  range((N - nxPoints) + 1, N - 1):
        wr[i]=[i - 1, i - nxPoints, i + 1]
        wq[i]=[i - 1, i - nxPoints - 1, i - nxPoints, i - nxPoints + 1, i + 1]
    cont = 0
    for i in range(nyPoints): #Creating de clusterPy areas
        nexty = acty - areaHeight
        for j in range(nxPoints):
            nextx = actx + areaWidth
            x1 = tuple([actx, acty])
            x2 = tuple([nextx, acty])
            x3 = tuple([nextx, nexty])
            x4 = tuple([actx, nexty])
            x5 = tuple([actx, acty])
            area = [x1, x2, x3, x4, x5]
            map.append([area])
            actx = nextx
            if cont not in disAreas: # Asigning the rest of the neighborhoods
                wr[cont]=[cont - 1, cont - nxPoints, cont + 1, cont + nxPoints]
                wq[cont]=[cont - 1, cont - nxPoints - 1, cont - nxPoints,
                        cont - nxPoints + 1, cont + 1, cont + nxPoints - 1,
                        cont + nxPoints, cont + nxPoints + 1]
            cont = cont + 1
        acty = nexty
        actx = xmin
    for i in range(N):
        Y[i]=[i]
    layer = Layer()
    layer.Y = Y
    layer.fieldNames = ['ID']
    layer.areas = map
    layer.Wrook = wr
    layer.Wqueen = wq
    layer.Wqueen, layer.Wrook, = weightsFromAreas(layer.areas)
    layer.shpType = 'polygon'
    layer.name = 'root'
    layer._defBbox()
    print "Done"
    return layer
示例#10
0
def createHexagonalGrid(nRows, nCols, lowerLeft=(0,0), upperRight=(100,100)):
    """Creates a new Layer with a hexagonal regular lattice
    
    :param nRows: number of rows
    :type nRows: integer
    :param nCols: number of columns
    :type nCols: integer
    :type lowerLeft: tuple or none, lower-left corner coordinates; default is (0,0) 
    :type upperRight: tuple or none, upper-right corner coordinates; default is (100,100)
    :rtype: Layer new lattice 

    **Description**

    Regular lattices are widely used in both theoretical and empirical
    applications in Regional Science. The example below shows how easy 
    the creation of this kind of maps is using clusterPy.
    
    **Examples**

    Create a grid of ten by ten points.::

        import clusterpy
        points = clusterpy.createGrid(10,10)
    
    Create a grid of ten by ten points on the bounding box (0,0,100,100).::

        import clusterpy
        points = clusterpy.createGrid(10, 10, lowerLeft=(0, 0), upperRight=(100, 100))
    """
    print "Creating grid"
    rowHeight = (upperRight[1] - lowerLeft[1])/float(nRows)
    colStep = rowHeight/float(2)
    N = nRows*nCols
    areas = []
    for row in range(nRows):
        actx = lowerLeft[0]
        for col in range(nCols):
            if col != 0:
                actx += 2*colStep
            if col%2 == 1:
                y0 = lowerLeft[1] + rowHeight*row - 2*rowHeight/float(2)
                y1 = lowerLeft[1] + rowHeight*row - rowHeight/float(2)
                y2 = lowerLeft[1] + rowHeight*row
            else:
                y0 = lowerLeft[1] + rowHeight*row - rowHeight/float(2)
                y1 = lowerLeft[1] + rowHeight*row
                y2 = lowerLeft[1] + rowHeight*row + rowHeight/float(2)
            x0 = actx
            x1 = actx + colStep
            x2 = actx + 2*colStep
            x3 = actx + 3*colStep
            pol = [(x0,y1),(x1,y2),(x2,y2),
                   (x3,y1),(x2,y0),(x1,y0),
                   (x0,y1)]
            areas.append([pol])
    Y = {}
    for i in range(N):
        Y[i]=[i]
    layer = Layer()
    layer.Y = Y
    layer.fieldNames = ['ID']
    layer.areas = areas
    layer.Wqueen, layer.Wrook, = weightsFromAreas(layer.areas)
    layer.shpType = 'polygon'
    layer.name = 'root'
    layer._defBbox()
    print "Done"
    return layer