示例#1
0
文件: Distance.py 项目: jkang1643/GIS
    def __init__(self,
                 data,
                 k=2,
                 p=2,
                 ids=None,
                 radius=None,
                 distance_metric='euclidean'):
        if isKDTree(data):
            self.kdtree = data
            self.data = data.data
        else:
            self.data = data
            self.kdtree = KDTree(data,
                                 radius=radius,
                                 distance_metric=distance_metric)
        self.k = k
        self.p = p
        this_nnq = self.kdtree.query(self.data, k=k + 1, p=p)

        to_weight = this_nnq[1]
        if ids is None:
            ids = list(range(to_weight.shape[0]))

        neighbors = {}
        for i, row in enumerate(to_weight):
            row = row.tolist()
            row.remove(i)
            row = [ids[j] for j in row]
            focal = ids[i]
            neighbors[focal] = row
        W.__init__(self, neighbors, id_order=ids)
示例#2
0
    def __init__(self, data, bandwidth=None, fixed=True, k=2,
                 function='triangular', eps=1.0000001, ids=None,
                 diagonal=False):
        if issubclass(type(data), scipy.spatial.KDTree):
            self.kdt = data
            self.data = self.kdt.data
            data = self.data
        else:
            self.data = data
            self.kdt = KDTree(self.data)
        self.k = k + 1
        self.function = function.lower()
        self.fixed = fixed
        self.eps = eps
        if bandwidth:
            try:
                bandwidth = np.array(bandwidth)
                bandwidth.shape = (len(bandwidth), 1)
            except:
                bandwidth = np.ones((len(data), 1), 'float') * bandwidth
            self.bandwidth = bandwidth
        else:
            self._set_bw()

        self._eval_kernel()
        neighbors, weights = self._k_to_W(ids)
        if diagonal:
            for i in neighbors:
                weights[i][neighbors[i].index(i)] = 1.0
        W.__init__(self, neighbors, weights, ids)
示例#3
0
    def __init__(self, data, threshold, p=2, alpha=-1.0, binary=True, ids=None,
            build_sp=True, silent=False):
        """Casting to floats is a work around for a bug in scipy.spatial.
        See detail in pysal issue #126.

        """
        self.p = p
        self.threshold = threshold
        self.binary = binary
        self.alpha = alpha
        self.build_sp = build_sp
        self.silent = silent
        
        if isKDTree(data):
            self.kd = data
            self.data = self.kd.data
        else:
            if self.build_sp:
                try:
                    data = np.asarray(data)
                    if data.dtype.kind != 'f':
                        data = data.astype(float)
                    self.data = data
                    self.kd = KDTree(self.data)
                except:
                    raise ValueError("Could not make array from data")        
            else:
                self.data = data
                self.kd = None       
        self._band()
        neighbors, weights = self._distance_to_W(ids)
        W.__init__(self, neighbors, weights, ids, silent_island_warning=self.silent)
示例#4
0
    def __init__(self,
                 data,
                 threshold,
                 p=2,
                 alpha=-1.0,
                 binary=True,
                 ids=None):
        """Casting to floats is a work around for a bug in scipy.spatial.
        See detail in pysal issue #126.

        """
        if isKDTree(data):
            self.kd = data
            self.data = self.kd.data
        else:
            try:
                data = np.asarray(data)
                if data.dtype.kind != 'f':
                    data = data.astype(float)
                self.data = data
                self.kd = KDTree(self.data)
            except:
                raise ValueError("Could not make array from data")

        self.p = p
        self.threshold = threshold
        self.binary = binary
        self.alpha = alpha
        self._band()
        neighbors, weights = self._distance_to_W(ids)
        W.__init__(self, neighbors, weights, ids)
示例#5
0
    def __init__(self,data,bandwidth=None,fixed=True,k=2, p=2,
                 function='triangular',eps=1.0000001,ids=None):

        # handle point_array
        if type(data).__name__=='ndarray':
            self.data=data
        elif type(data).__name__=='list':
            self.data=data
        else:
            raise Exception, 'Unsupported type'
        self.k=k+1 
        self.function=function.lower()
        self.fixed=fixed
        self.eps=eps
        self.kdt=KDTree(self.data)
        self.dmat,self.neigh=self.kdt.query(data,k=k+1,p=p)
        if bandwidth:
            try:
                bandwidth=np.array(bandwidth)
                bandwidth.shape=(len(bandwidth),1)
            except:
                bandwidth=np.ones((len(data),1),'float')*bandwidth
            self.bandwidth=bandwidth
        else:
            self._set_bw()

        self._eval_kernel()
        neighbors, weights = self._k_to_W(ids)
        W.__init__(self,neighbors,weights,ids)
示例#6
0
    def __init__(self, data, threshold, p=2, alpha=-1.0, binary=True, ids=None):
        """Casting to floats is a work around for a bug in scipy.spatial.
        See detail in pysal issue #126.

        """
        if issubclass(type(data), scipy.spatial.KDTree):
            self.kd = data
            self.data = self.kd.data
        else:
            try:
                data = np.asarray(data)
                if data.dtype.kind != 'f':
                    data = data.astype(float)
                self.data = data
                self.kd = KDTree(self.data)
            except:
                raise ValueError("Could not make array from data")

        self.p = p
        self.threshold = threshold
        self.binary = binary
        self.alpha = alpha
        self._band()
        neighbors, weights = self._distance_to_W(ids)
        W.__init__(self, neighbors, weights, ids)
示例#7
0
文件: Distance.py 项目: surfcao/pysal
    def __init__(self, data, bandwidth=None, fixed=True, k=2,
                 function='triangular', eps=1.0000001, ids=None,
                 diagonal=False):
        if issubclass(type(data), scipy.spatial.KDTree):
            self.kdt = data
            self.data = self.kdt.data
            data = self.data
        else:
            self.data = data
            self.kdt = KDTree(self.data)
        self.k = k + 1
        self.function = function.lower()
        self.fixed = fixed
        self.eps = eps
        if bandwidth:
            try:
                bandwidth = np.array(bandwidth)
                bandwidth.shape = (len(bandwidth), 1)
            except:
                bandwidth = np.ones((len(data), 1), 'float') * bandwidth
            self.bandwidth = bandwidth
        else:
            self._set_bw()

        self._eval_kernel()
        neighbors, weights = self._k_to_W(ids)
        if diagonal:
            for i in neighbors:
                nis = neighbors[i]
                weights[i][neighbors[i].index(i)] = 1.0
        W.__init__(self, neighbors, weights, ids)
示例#8
0
    def read_old_version(self, header):
        """
        Read the old version of ArcGIS(<10.1) swm file
        :param header:
        :return:
        """
        id_var, srs = header[:-1].split(';')
        self.varName = id_var
        self.srs = srs
        self.header_len = len(header) + 8
        no_obs, row_std = tuple(unpack('<2l', self.file.read(8)))
        neighbors = {}
        weights = {}
        for i in xrange(no_obs):
            origin, no_nghs = tuple(unpack('<2l', self.file.read(8)))
            neighbors[origin] = []
            weights[origin] = []
            if no_nghs > 0:
                neighbors[origin] = list(
                    unpack('<%il' % no_nghs, self.file.read(4 * no_nghs)))
                weights[origin] = list(
                    unpack('<%id' % no_nghs, self.file.read(8 * no_nghs)))
                w_sum = list(unpack('<d', self.file.read(8)))[0]

        self.pos += 1
        return W(neighbors, weights)
示例#9
0
    def _read(self):
        if self.pos > 0:
            raise StopIteration

        fbody = self.file.read()
        body_structure = {}
        for i in ['num', 'adj', 'weights', 'sumNumNeigh']:
            i_loc = fbody.find(i)
            if i_loc != -1:
                body_structure[i] = (i_loc, i)
        body_sequence = sorted(body_structure.values())
        body_sequence.append((-1, 'eof'))

        for i in range(len(body_sequence) - 1):
            part, next_part = body_sequence[i], body_sequence[i + 1]
            start, end = part[0], next_part[0]
            part_text = fbody[start:end]

            part_length, start, end = len(part_text), 0, -1
            for c in range(part_length):
                if part_text[c].isdigit():
                    start = c
                    break

            for c in range(part_length - 1, 0, -1):
                if part_text[c].isdigit():
                    end = c + 1
                    break
            part_text = part_text[start:end]
            part_text = part_text.replace('\n', '')
            value_type = int
            if part[1] == 'weights':
                value_type = float
            body_structure[part[1]] = [
                value_type(v) for v in part_text.split(',')
            ]

        cardinalities = body_structure['num']
        adjacency = body_structure['adj']
        raw_weights = [1.0] * int(sum(cardinalities))
        if 'weights' in body_structure and isinstance(
                body_structure['weights'], list):
            raw_weights = body_structure['weights']

        no_obs = len(cardinalities)
        neighbors = {}
        weights = {}
        pos = 0
        for i in range(no_obs):
            neighbors[i + 1] = []
            weights[i + 1] = []
            no_nghs = cardinalities[i]
            if no_nghs > 0:
                neighbors[i + 1] = adjacency[pos:pos + no_nghs]
                weights[i + 1] = raw_weights[pos:pos + no_nghs]
            pos += no_nghs

        self.pos += 1
        return W(neighbors, weights)
def swm2Weights(swmFile, master2Order=None):
    swm = WU.SWMReader(swmFile)
    numObs = swm.numObs
    adjust = False

    if master2Order and len(master2Order) < numObs:
        msg = ("The spatial attributes have fewer entries than spatial"
               "weights! Weights will be adjusted dynamically...")
        ARCPY.AddWarning(msg)
        adjust = True

    neighs = {}
    w = {}
    rowStandard = swm.rowStandard
    for i in range(numObs):
        masterID, nn, nhsTemp, weightsTemp, sumUnstandard = swm.swm.readEntry()
        if master2Order == None:
            # no need adjust when convert directly from weights content
            orderID = masterID
            nhIDs = nhsTemp
            weights = weightsTemp

        elif masterID in master2Order:
            orderID = master2Order[masterID]
            if not adjust:
                nhIDs = [master2Order[nh] for nh in nhsTemp]
                weights = weightsTemp
            else:
                # Restandardize Due to Subset/Select
                nhIDs = []
                weights = []
                if nn:
                    for i in range(nn):
                        nh = nhsTemp[i]
                        if nh in master2Order:
                            nhOrder = master2Order[nh]
                            nhIDs.append(nhOrder)
                            nhWeight = weightsTemp[i]
                            if rowStandard:
                                # Unstandardize if Necessary
                                nhWeight = nhWeight * sumUnstandard[0]
                            weights.append(nhWeight)

                # Re-Standardize
                if nhIDs:
                    weights = NUM.array(weights)
                    if rowStandard:
                        weights = (1.0 / weights.sum()) * weights

        # Add To Dict Structures
        neighs[orderID] = nhIDs
        w[orderID] = weights

    swm.close()
    wobj = W(neighs, w)
    wobj._varName = swm.masterField
    return wobj
示例#11
0
    def _read(self):
        """
        Reads ArcGIS swm file.
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open an ArcGIS swm file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('ohio.swm'),'r').read()

        Get the number of observations from the header

        >>> w.n
        88

        Get the mean number of neighbors

        >>> w.mean_neighbors
        5.25

        Get neighbor distances for a single observation

        >>> w[1]
        {2: 1.0, 11: 1.0, 6: 1.0, 7: 1.0}

        """

        if self.pos > 0:
            raise StopIteration

        header01 = self.file.readline()
        header01 = header01.decode()
        id_var, srs = header01[:-1].split(';')
        self.varName = id_var
        self.header_len = len(header01) + 8
        no_obs, row_std = tuple(unpack('<2l', self.file.read(8)))

        neighbors = {}
        weights = {}
        for i in xrange(no_obs):
            origin, no_nghs = tuple(unpack('<2l', self.file.read(8)))
            neighbors[origin] = []
            weights[origin] = []
            if no_nghs > 0:
                neighbors[origin] = list(
                    unpack('<%il' % no_nghs, self.file.read(4 * no_nghs)))
                weights[origin] = list(
                    unpack('<%id' % no_nghs, self.file.read(8 * no_nghs)))
                w_sum = list(unpack('<d', self.file.read(8)))[0]

        self.pos += 1
        return W(neighbors, weights)
示例#12
0
 def __init__(self, data, k=2, p=2, ids=None, radius=None, distance_metric='euclidean'):
     if isKDTree(data):
         self.kdtree = data
         self.data = data.data
     else:
         self.data = data
         self.kdtree = KDTree(data, radius=radius, distance_metric=distance_metric)
     self.k = k 
     self.p = p
     this_nnq = self.kdtree.query(self.data, k=k+1, p=p)
     
     to_weight = this_nnq[1]
     if ids is None:
         ids = list(range(to_weight.shape[0]))
     
     neighbors = {}
     for i,row in enumerate(to_weight):
         row = row.tolist()
         row.remove(i)
         row = [ids[j] for j in row]
         focal = ids[i]
         neighbors[focal] = row
     W.__init__(self, neighbors, id_order=ids)
示例#13
0
    def buildWeights(self):
        """Performs Contiguity-based Weights Creation."""
        ARCPY.SetProgressor("default",
                            "Constructing spatial weights object...")

        #### Shorthand Attributes ####
        ssdo = self.ssdo
        isLowOrder = self.isLowOrder
        weightOrder = self.weightOrder

        #### Get Neighbor Dictionary for All Polygons ####
        master2Order = ssdo.master2Order
        polyNeighborDict = WU.polygonNeighborDict(self.inputFC, \
                                                  self.masterField, \
                                                  contiguityType=self.weightType)

        #### Assign empty list to polygons without neighbors ####
        if ssdo.numObs > len(polyNeighborDict):
            for masterKey in master2Order.keys():
                if not polyNeighborDict.has_key(masterKey):
                    polyNeighborDict[masterKey] = []

        #### Convert DefaultDict to Real Dict ?####
        if not self.idField:
            polyNeighborCopy = {}
            for key in polyNeighborDict.keys():
                polyNeighborCopy[master2Order[key]] = []
                for item in polyNeighborDict[key]:
                    polyNeighborCopy[master2Order[key]].\
                        append(master2Order[item])
            polyNeighborDict = polyNeighborCopy

        #### Create a PySAL W Object ####
        weightObj = W(polyNeighborDict)

        #### Building up Lower Order Spatial Weights ####
        if weightOrder > 1:
            ARCPY.SetProgressor("default", \
                                "Building up Lower Order Spatial Weights...")
            origWeight = weightObj
            weightObj = PYSAL.higher_order(weightObj, weightOrder)
            if isLowOrder:
                for order in xrange(weightOrder - 1, 1, -1):
                    lowOrderW = PYSAL.higher_order(origWeight, order)
                    weightObj = PYSAL.w_union(weightObj, lowOrderW)
                weightObj = PYSAL.w_union(weightObj, origWeight)

        #### Save weightObj Class Object for Writing Result ####
        self.weightObj = weightObj
示例#14
0
    def __init__(self,
                 data,
                 bandwidth=None,
                 fixed=True,
                 k=2,
                 p=2,
                 function='triangular',
                 eps=1.0000001,
                 ids=None):

        # handle point_array
        if type(data).__name__ == 'ndarray':
            self.data = data
        elif type(data).__name__ == 'list':
            self.data = data
        else:
            raise Exception, 'Unsupported type'
        self.k = k + 1
        self.function = function.lower()
        self.fixed = fixed
        self.eps = eps
        self.kdt = KDTree(self.data)
        self.dmat, self.neigh = self.kdt.query(data, k=k + 1, p=p)
        if bandwidth:
            try:
                bandwidth = np.array(bandwidth)
                bandwidth.shape = (len(bandwidth), 1)
            except:
                bandwidth = np.ones((len(data), 1), 'float') * bandwidth
            self.bandwidth = bandwidth
        else:
            self._set_bw()

        self._eval_kernel()
        neighbors, weights = self._k_to_W(ids)
        W.__init__(self, neighbors, weights, ids)
示例#15
0
    def read_new_version(self, header_line):
        """
        Read the new version of ArcGIS(<10.1) swm file, which contains more parameters
        and records weights in two ways: fixed or variable
        :param header_line: str, the firs line of the swm file, which contains a lot of parameters.
                            The parameters are divided by ";" and the key-value of each parameter is divided by "@"
        :return:
        """
        headerDict = {}
        for item in header_line.split(";"):
            key, value = item.split("@")
            headerDict[key] = value
        # for the reader, in order to generate the PySAL Weight class, only a few of the parameters are needed.
        self.varName = headerDict["UNIQUEID"]
        self.srs = headerDict["SPATIALREFNAME"]

        fixedWeights = False
        if "FIXEDWEIGHTS" in headerDict:
            fixedWeights = headerDict["FIXEDWEIGHTS"].upper().strip() == 'TRUE'

        no_obs, row_std = tuple(unpack('<2l', self.file.read(8)))
        is_row_standard = row_std == 1

        neighbors = {}
        weights = {}
        for i in xrange(no_obs):
            origin, no_nghs = tuple(unpack('<2l', self.file.read(8)))
            neighbors[origin] = []
            weights[origin] = []
            if no_nghs > 0:
                neighbors[origin] = list(
                    unpack('<%il' % no_nghs, self.file.read(4 * no_nghs)))
                if fixedWeights:
                    weights[origin] = list(unpack('<d',
                                                  self.file.read(8))) * no_nghs
                else:
                    weights[origin] = list(
                        unpack('<%id' % no_nghs, self.file.read(8 * no_nghs)))
                w_sum = list(unpack('<d', self.file.read(8)))[0]

        self.pos += 1
        return W(neighbors, weights)
示例#16
0
    def buildWeights(self):
        """Performs Distance-based Weights Creation"""
        ARCPY.SetProgressor("default",
                            "Constructing spatial weights object...")

        #### Shorthand Attributes ####
        distanceType = self.distanceType
        threshold = self.threshold
        knnNum = self.knnNum
        idField = self.idField
        outputExt = self.outputExt
        ssdo = self.ssdo

        #### Create Distance-based WeightObj (0-based IDs) ####
        dataArray = ssdo.xyCoords
        if distanceType.upper() == DISTTYPE[0]:
            weightObj = PYSAL.threshold_binaryW_from_array(
                dataArray, threshold)
        elif distanceType.upper() == DISTTYPE[1]:
            weightObj = PYSAL.knnW_from_array(dataArray, knnNum)
        elif distanceType.upper() == DISTTYPE[2]:
            alpha = -1 * self.inverseDist
            weightObj = PYSAL.threshold_continuousW_from_array(\
                dataArray, threshold, alpha=alpha)

        #### Re-Create WeightObj for NOT 0-based idField ####
        if idField:
            if ssdo.master2Order.keys() != ssdo.master2Order.values():
                o2M = ssdo.order2Master
                neighborDict = {o2M[oid] : [o2M[nid] for nid in nbrs] \
                                for oid,nbrs in weightObj.neighbors.items()}
                weightDict = {o2M[oid] : weights \
                              for oid, weights in weightObj.weights.items()}
                weightObj = W(neighborDict, weightDict)

        #### Save weightObj Class Object for Writing Result ####
        self.weightObj = weightObj
    def _read(self):
        """Reads .dat file
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open .dat file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('wmat.dat'),'r').read()

        Get the number of observations from the header

        >>> w.n
        49

        Get the mean number of neighbors

        >>> w.mean_neighbors
        4.7346938775510203

        Get neighbor distances for a single observation

        >>> w[1]
        {2.0: 0.3333, 5.0: 0.3333, 6.0: 0.3333}

        """
        if self.pos > 0:
            raise StopIteration

        id_type = float
        weights, neighbors = self._readlines(id_type)

        self.pos += 1
        return W(neighbors, weights)
示例#18
0
    def _read(self):
        """Reads STATA Text file
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open a text file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('stata_sparse.txt'),'r','stata_text').read()
        WARNING: there are 7 disconnected observations
        Island ids:  [5, 9, 10, 11, 12, 14, 15]

        Get the number of observations from the header

        >>> w.n
        56

        Get the mean number of neighbors

        >>> w.mean_neighbors
        4.0

        Get neighbor distances for a single observation

        >>> w[1]
        {53: 1.0, 51: 1.0, 45: 1.0, 54: 1.0, 7: 1.0}

        """
        if self.pos > 0:
            raise StopIteration

        n = int(self.file.readline().strip())
        line1 = self.file.readline().strip()
        obs_01 = line1.split(' ')
        matrix_form = False
        if len(obs_01) == 1 or float(obs_01[1]) != 0.0:
            def line2wgt(line):
                row = [int(i) for i in line.strip().split(' ')]
                return row[0], row[1:], [1.0] * len(row[1:])
        else:
            matrix_form = True

            def line2wgt(line):
                row = line.strip().split(' ')
                obs = int(float(row[0]))
                ngh, wgt = [], []
                for i in range(n):
                    w = float(row[i + 1])
                    if w > 0:
                        ngh.append(i)
                        wgt.append(w)
                return obs, ngh, wgt

        id_order = []
        weights, neighbors = {}, {}
        l = line1
        for i in range(n):
            obs, ngh, wgt = line2wgt(l)
            id_order.append(obs)
            neighbors[obs] = ngh
            weights[obs] = wgt
            l = self.file.readline()
        if matrix_form:
            for obs in neighbors:
                neighbors[obs] = [id_order[ngh] for ngh in neighbors[obs]]

        self.pos += 1
        return W(neighbors, weights)
    def _read(self):
        """
        Reads Lotus Wk1 file

        Returns
        -------
        A pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open a Lotus Wk1 file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('spat-sym-us.wk1'),'r').read()

        Get the number of observations from the header

        >>> w.n
        46

        Get the mean number of neighbors

        >>> w.mean_neighbors
        4.0869565217391308

        Get neighbor distances for a single observation

        >>> w[1]
        {25: 1.0, 3: 1.0, 28: 1.0, 39: 1.0}

        """
        if self.pos > 0:
            raise StopIteration

        bof = struct.unpack('<6B', self.file.read(6))
        if bof != (0, 0, 2, 0, 6, 4):
            raise ValueError('The header of your file is wrong!')

        neighbors = {}
        weights = {}
        dtype, dlen = struct.unpack('<2H', self.file.read(4))
        while (dtype != 1):
            if dtype in [13, 14, 16]:
                self.file.read(1)
                row, column = struct.unpack('2H', self.file.read(4))
                format, length = '<d', 8
                if dtype == 13:
                    format, length = '<h', 2
                value = float(struct.unpack(format, self.file.read(length))[0])
                if value > 0:
                    ngh = neighbors.setdefault(row, [])
                    ngh.append(column)
                    wgt = weights.setdefault(row, [])
                    wgt.append(value)
                if dtype == 16:
                    self.file.read(dlen - 13)
            elif dtype == 11:
                self.file.read(24)
            else:
                self.file.read(dlen)
            dtype, dlen = struct.unpack('<2H', self.file.read(4))

        self.pos += 1
        return W(neighbors, weights)
    def _read(self):
        """Reads .gwt file
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(f)' at the interpreter to see what methods are supported.
        Open .gwt file and read it into a pysal weights object

        >>> f = pysal.open(pysal.examples.get_path('juvenile.gwt'),'r').read()

        Get the number of observations from the header

        >>> f.n
        168

        Get the mean number of neighbors

        >>> f.mean_neighbors
        16.678571428571427

        Get neighbor distances for a single observation

        >>> f[1]
        {2: 14.1421356}


        """
        if self.pos > 0:
            raise StopIteration

        flag, n, shp, id_var = self.file.readline().strip().split()
        self.shpName = shp
        self.varName = id_var
        id_order = None
        id_type = str
        try:
            base = os.path.split(self.dataPath)[0]
            dbf = os.path.join(base, self.shpName.replace('.shp', '') + '.dbf')
            if os.path.exists(dbf):
                db = pysal.open(dbf, 'r')
                if id_var in db.header:
                    id_order = db.by_col(id_var)
                    id_type = type(id_order[0])
                else:
                    warn(
                        "ID_VAR:'%s' was not in the DBF header, proceeding with unordered string ids."
                        % (id_var), RuntimeWarning)
            else:
                warn(
                    "DBF relating to GWT was not found, proceeding with unordered string ids.",
                    RuntimeWarning)
        except:
            warn(
                "Exception occurred will reading DBF, proceeding with unordered string ids.",
                RuntimeWarning)
        self.flag = flag
        self.n = n
        self.shp = shp
        self.id_var = id_var
        if id_order is None:
            weights, neighbors, id_order = self._readlines(id_type, True)
        else:
            weights, neighbors = self._readlines(id_type)

        self.pos += 1
        w = W(neighbors, weights, id_order)
        #w.transform = 'b'
        #set meta data
        w._shpName = self.shpName
        w._varName = self.varName
        #warn("Weights have been converted to binary. To retrieve original values use w.transform='o'", RuntimeWarning)
        return w
示例#21
0
    def _read(self):
        """
        Parameters
        ----------
        reads in a GalIO object

        Returns
        -------
        returns a W object

        Examples
        --------

        >>> import tempfile, pysal, os

        Read in a file GAL file

        >>> testfile = pysal.open(pysal.examples.get_path('sids2.gal'),'r')

        Return a W object

        >>> w = testfile.read()
        >>> w.n == 100
        True
        >>> w.sd == 1.5151237573214935
        True
        >>> testfile = pysal.open(pysal.examples.get_path('sids2.gal'),'r')

        Return a sparse matrix for the w information

        >>> wsp = testfile.read(sparse=True)
        >>> wsp.sparse.nnz
        462

        """
        if self._sparse:
            if self.pos > 0:
                raise StopIteration

            header = self.file.readline().strip().split()
            header_n = len(header)
            n = int(header[0])
            if header_n > 1:
                n = int(header[1])
            ids = []
            idsappend = ids.append
            row = []
            extend = row.extend  # avoid dot in loops
            col = []
            append = col.append
            counter = 0
            typ = self.data_type
            for i in range(n):
                id, n_neighbors = self.file.readline().strip().split()
                id = typ(id)
                n_neighbors = int(n_neighbors)
                neighbors_i = list(
                    map(typ,
                        self.file.readline().strip().split()))
                nn = len(neighbors_i)
                extend([id] * nn)
                counter += nn
                for id_neigh in neighbors_i:
                    append(id_neigh)
                idsappend(id)
            self.pos += 1
            row = np.array(row)
            col = np.array(col)
            data = np.ones(counter)
            ids = np.unique(row)
            row = np.array([np.where(ids == j)[0] for j in row]).flatten()
            col = np.array([np.where(ids == j)[0] for j in col]).flatten()
            spmat = sparse.csr_matrix((data, (row, col)), shape=(n, n))
            return WSP(spmat)

        else:
            if self.pos > 0:
                raise StopIteration
            neighbors = {}
            ids = []
            # handle case where more than n is specified in first line
            header = self.file.readline().strip().split()
            header_n = len(header)
            n = int(header[0])
            if header_n > 1:
                n = int(header[1])
            w = {}
            typ = self.data_type
            for i in range(n):
                id, n_neighbors = self.file.readline().strip().split()
                id = typ(id)
                n_neighbors = int(n_neighbors)
                neighbors_i = list(
                    map(typ,
                        self.file.readline().strip().split()))
                neighbors[id] = neighbors_i
                ids.append(id)
            self.pos += 1
            return W(neighbors, id_order=ids)
示例#22
0
    def _read(self):
        """Reads ArcGIS dbf file
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open an ArcGIS dbf file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('arcgis_ohio.dbf'),'r','arcgis_dbf').read()

        Get the number of observations from the header

        >>> w.n
        88

        Get the mean number of neighbors

        >>> w.mean_neighbors
        5.25

        Get neighbor distances for a single observation

        >>> w[1]
        {2: 1.0, 11: 1.0, 6: 1.0, 7: 1.0}

        """
        if self.pos > 0:
            raise StopIteration

        id_var = self.file.header[1]
        startPos = len(self.file.header)

        if startPos == 3:
            startPos = 0
        elif startPos == 4:
            startPos = 1
        else:
            raise ValueError(
                "Wrong structure, a weights dbf file requires at least three data columns"
            )

        self.varName = id_var
        id_type = int
        id_spec = self.file.field_spec[startPos]
        if id_spec[0] != 'N':
            raise TypeError('The data type for ids should be integer.')
        self.id_var = id_var

        weights = {}
        neighbors = {}
        for row in self.file:
            i, j, w = tuple(row)[startPos:]
            i = id_type(i)
            j = id_type(j)
            w = float(w)
            if i not in weights:
                weights[i] = []
                neighbors[i] = []
            weights[i].append(w)
            neighbors[i].append(j)
            self.pos = self.file.pos

        return W(neighbors, weights)
    def _read(self):
        """Reads ArcGIS Text file
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open a text file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('arcgis_txt.txt'),'r','arcgis_text').read()

        Get the number of observations from the header

        >>> w.n
        3

        Get the mean number of neighbors

        >>> w.mean_neighbors
        2.0

        Get neighbor distances for a single observation

        >>> w[1]
        {2: 0.1, 3: 0.14286}

        """
        if self.pos > 0:
            raise StopIteration

        id_var = self.file.readline().strip()
        self.varName = id_var
        id_order = None
        id_type = int
        try:
            dbf = os.path.join(self.dataPath + '.dbf')
            if os.path.exists(dbf):
                db = pysal.open(dbf, 'r')
                if id_var in db.header:
                    id_order = db.by_col(id_var)
                    id_type = type(id_order[0])
                else:
                    warn("ID_VAR:'%s' was in in the DBF header, proceeding with unordered string ids." % (id_var), RuntimeWarning)
            else:
                warn("DBF relating to ArcGIS TEXT was not found, proceeding with unordered string ids.", RuntimeWarning)
        except:
            warn("Exception occurred will reading DBF, proceeding with unordered string ids.", RuntimeWarning)

        if (id_type is not int) or (id_order and type(id_order)[0] is not int):
            raise TypeError("The data type for ids should be integer.")

        if id_order:
            self.n = len(id_order)
            self.shp = os.path.split(self.dataPath)[1].split('.')[0]
        self.id_var = id_var

        weights, neighbors = self._readlines(id_type)
        for k in neighbors:
            if k in neighbors[k]:
                k_index = neighbors[k].index(k)
                if weights[k][k_index] == 0.0:
                    del neighbors[k][k_index]
                    del weights[k][k_index]

        self.pos += 1
        return W(neighbors, weights)
def text2Weights(weightsFile, master2Order=None):

    adjust = False
    numObs = getFeatNumFromWeights(weightsFile)
    if master2Order:
        if len(master2Order) < numObs:
            msg = ("The spatial attributes have fewer entries than spatial "
                   "weights! Weights will be adjusted dynamically...")
            ARCPY.AddWarning(msg)
            adjust = True

    uid = None
    neighDict = {}
    weightDict = {}
    orderID = None
    inType = OS.path.splitext(weightsFile)[-1].upper()

    fi = open(weightsFile, "r")
    info = fi.readline().strip()
    for item in info.split(" "):
        if not item.isdigit() and item.lower() != "unknown" \
           and len(item) > 0:
            uid = item
            break
    if uid == None:
        msg = ("A unique ID entry was not found in the weights file. Please "
               "check the weights file.")
        ARCPY.AddError(msg)
        raise SystemExit()

    if inType == ".GAL":
        # read 2 lines at a time
        line = fi.readline()
        while line:
            # read line for id and #neighbors
            masterID, nn = [int(i) for i in line.strip().split()]
            orderID = None
            if not adjust:
                try:
                    if master2Order:
                        orderID = master2Order[masterID]
                    else:
                        orderID = masterID
                except:
                    msg = ("A unique Master ID entry was not found in the "
                           "spatial dataset! Invaid GAL File...")
                    ARCPY.AddError(msg)
                    raise SystemExit()
            else:
                if masterID in master2Order:
                    orderID = int(master2Order[masterID])
                #### Check Unique ID ####
                if orderID in neighDict:
                    ARCPY.AddIDMessage("Error", 644, "UNIQUE_ID")
                    ARCPY.AddIDMessage("Error", 643)
                    raise SystemExit()

            # read next line for neighbor ids
            line = fi.readline()
            if orderID is not None:
                neighIDs = [int(i) for i in line.strip().split()]
                if not adjust:
                    try:
                        if master2Order:
                            neighs = [master2Order[i] for i in neighIDs]
                        else:
                            neighs = neighIDs
                        neighDict[orderID] = neighs
                        weightDict[orderID] = [1. for i in neighs]
                    except:
                        msg = ("A unique ID entry" + uid +
                               " was not found in the "
                               "spatial dataset! Invalid GAL file...")
                        ARCPY.AddError(msg)
                        raise SystemExit()
                else:
                    neighDict[orderID] = []
                    weightDict[orderID] = []

                    for curMasterID in neighIDs:
                        if curMasterID in master2Order:
                            neighDict[orderID].append(
                                master2Order[curMasterID])
                            weightDict[orderID].append(1.)

                    weightArray = NUM.array(weightDict[orderID])
                    if len(weightArray) > 0:
                        weightArray = 1.0 * weightArray / len(weightArray)
                        weightDict[orderID] = weightArray.tolist()

            line = fi.readline()

    # inType not GAL
    else:
        for line in fi:
            masterID, nid, weight = line.strip().split()
            masterID = int(masterID)
            nid = int(nid)

            if not adjust:
                try:
                    if master2Order:
                        orderID = master2Order[masterID]
                        neighID = master2Order[nid]
                    else:
                        orderID = masterID
                        neighID = nid
                except:
                    msg = ("A unique Master ID entry was not found in the "
                           "spatial dataset! Invalid GWT File...")
                    ARCPY.AddError(msg)
                    raise SystemExit()

                #### Process Intersection in Weights Matrix ####
                if orderID not in neighDict:
                    neighDict[orderID] = []
                    weightDict[orderID] = []
                try:
                    neighDict[orderID].append(neighID)
                    weightDict[orderID].append(LOCALE.atof(weight))
                except:
                    msg = ("Parsing error encountered while creating spatial "
                           "weights object...")
                    ARCPY.AddError(msg)
                    raise SystemExit()
            else:
                if masterID in master2Order:
                    orderID = master2Order[masterID]
                    if orderID not in neighDict:
                        neighDict[orderID] = []
                        weightDict[orderID] = []
                    if nid in master2Order:
                        orderNID = master2Order[nid]
                        neighDict[orderID].append(orderNID)
                        weightDict[orderID].append(LOCALE.atof(weight))
        # restandardization
        if adjust:
            for orderID in weightDict.keys():
                if len(weightDict[orderID]) > 0:
                    sumWeight = 0.0
                    for item in weightDict[orderID]:
                        sumWeight += item
                    weightArray = 1.0 * NUM.array(
                        weightDict[orderID]) / sumWeight
                    weightDict[orderID] = weightArray.tolist()
    fi.close()
    if returnWeightFileType(weightsFile) == 'GWT' and master2Order:
        for neighKey in master2Order.keys():
            orderID = int(master2Order[int(neighKey)])
            if orderID not in neighDict:
                neighDict[orderID] = []
                weightDict[orderID] = []

    w = W(neighDict, weightDict)
    if inType == ".GAL":
        w.transform = 'r'

    w._varName = uid
    return w
示例#25
0
    def _read(self):
        """Reads GeoBUGS text file
        Returns a pysal.weights.weights.W object

        Examples
        --------

        Type 'dir(w)' at the interpreter to see what methods are supported.
        Open a GeoBUGS text file and read it into a pysal weights object

        >>> w = pysal.open(pysal.examples.get_path('geobugs_scot'),'r','geobugs_text').read()
        WARNING: there are 3 disconnected observations
        Island ids:  [6, 8, 11]

        Get the number of observations from the header

        >>> w.n
        56

        Get the mean number of neighbors

        >>> w.mean_neighbors
        4.1785714285714288

        Get neighbor distances for a single observation

        >>> w[1]
        {9: 1.0, 19: 1.0, 5: 1.0}

        """
        if self.pos > 0:
            raise StopIteration

        fbody = self.file.read()
        body_structure = {}
        for i in ['num', 'adj', 'weights', 'sumNumNeigh']:
            i_loc = fbody.find(i)
            if i_loc != -1:
                body_structure[i] = (i_loc, i)
        body_sequence = sorted(body_structure.values())
        body_sequence.append((-1, 'eof'))

        for i in range(len(body_sequence) - 1):
            part, next_part = body_sequence[i], body_sequence[i + 1]
            start, end = part[0], next_part[0]
            part_text = fbody[start:end]

            part_length, start, end = len(part_text), 0, -1
            for c in xrange(part_length):
                if part_text[c].isdigit():
                    start = c
                    break

            for c in xrange(part_length - 1, 0, -1):
                if part_text[c].isdigit():
                    end = c + 1
                    break
            part_text = part_text[start: end]
            part_text = part_text.replace('\n', '')
            value_type = int
            if part[1] == 'weights':
                value_type = float
            body_structure[part[1]] = [value_type(v)
                                       for v in part_text.split(',')]

        cardinalities = body_structure['num']
        adjacency = body_structure['adj']
        raw_weights = [1.0] * int(sum(cardinalities))
        if 'weights' in body_structure and isinstance(body_structure['weights'], list):
            raw_weights = body_structure['weights']

        no_obs = len(cardinalities)
        neighbors = {}
        weights = {}
        pos = 0
        for i in xrange(no_obs):
            neighbors[i + 1] = []
            weights[i + 1] = []
            no_nghs = cardinalities[i]
            if no_nghs > 0:
                neighbors[i + 1] = adjacency[pos: pos + no_nghs]
                weights[i + 1] = raw_weights[pos: pos + no_nghs]
            pos += no_nghs

        self.pos += 1
        return W(neighbors, weights)
def netW(link_list, share='A', transform = 'r'):
    """
    Create a network-contiguity based weight object based on different nodal
    relationships encoded in a network.

    Parameters
    ----------
    link_list   : list 
                  of tuples where each tuple is of the form (o,d) where o is an
                  origin id and d is a destination id

    share       : string
                  denoting how to define the nodal relationship used to
                  determine neighboring edges; defualt is 'A' for any shared
                  nodes between two network edges; options include:
                    'A': any shared nodes 
                    'O': a shared origin node
                    'D': a shared destination node
                    'OD' a shared origin node or a shared destination node
                    'C': a shared node that is the destination of the first
                         edge and the origin of the second edge - i.e., a
                         directed chain is formed moving from edge one to edge
                         two.

    transform   : Transformation for standardization of final OD spatial weight; default
                  is 'r' for row standardized
       
    Returns
    -------
     W          : nodal contiguity W object for networkd edges or flows
                  W Object representing the binary adjacency of the network edges
                  given a definition of nodal relationships.

    Examples
    --------

    >>> links = [('a','b'), ('a','c'), ('a','d'), ('c','d'), ('c', 'b'), ('c','a')]
    >>> O = pysal.weights.spintW.netW(links, share='O')
    >>> W.neighbors[('a', 'b')]
    [('a', 'c'), ('a', 'd')]
    >>> OD = pysal.weights.spintW.netW(links, share='OD')
    >>> OD.neighbors[('a', 'b')]
    [('a', 'c'), ('a', 'd'), ('c', 'b')]
    >>> any_common = pysal.weights.spintW.netw(links, share='A')
    [('a', 'c'), ('a', 'd'), ('c', 'b'), ('c', 'a')]

    """
    neighbors = {}
    neighbors = OrderedDict()
    edges = link_list
    for key in edges:
        neighbors[key] = []
        for neigh in edges:
            if key == neigh:
                continue
            if share.upper() == 'OD':
                if key[0] == neigh[0] or key[1] == neigh[1]:
                    neighbors[key].append(neigh)
            elif share.upper() == 'O':
                if key[0] == neigh[0]:
                    neighbors[key].append(neigh)
            elif share.upper() == 'D':
                if key[1] == neigh[1]:
                	neighbors[key].append(neigh)
            elif share.upper() == 'C':
                if key[1] == neigh[0]:
                    neighbors[key].append(neigh)
            elif share.upper() == 'A':
                if key[0] == neigh[0] or key[0] == neigh[1] or \
                	key[1] == neigh[0] or key[1] == neigh[1]:
                    neighbors[key].append(neigh)
            else:
                raise AttributeError("Parameter 'share' must be 'O', 'D',"
                       " 'OD', or 'C'")
    netW = W(neighbors)
    netW.tranform = transform
    return netW