コード例 #1
0
    def get_voronoi(self, uid):
        rlat, rlon = self.latlons[uid]
        nbrs = [gid for gid in self.nbrs[uid] if gid != -1]
        latlon_nbrs = [self.latlons[self.uids[gid]] for gid in nbrs]

        x0, y0 = latlon2xyp(rlat,rlon,rlat,rlon)[1]
        xy_nbrs = [latlon2xyp(lat,lon,rlat,rlon)[1] for lat,lon in latlon_nbrs]


        #------------------------------------------
        # Generate a Voronoi diagram
        vor = Voronoi([(x0,y0)]+xy_nbrs)


        #------------------------------------------
        # Remove non-neighbor points
        ridge_pts = [sorted(pair) for pair in vor.ridge_points]
        xy_nbrs2 = [xy_nbrs[i] for i in xrange(len(nbrs)) \
                               if [0,i+1] in ridge_pts]
        if len(xy_nbrs2) < len(nbrs):
            vor = Voronoi([(x0,y0)]+xy_nbrs2)

        #for nbr, xy in zip(nbrs, xy_nbrs2):
        #    print nbr, self.gq_indices[nbr], xy


        #------------------------------------------
        # Sort the vertices
        ridge_pts = [sorted(pair) for pair in vor.ridge_points]
        vidxs = list()

        for inb in xrange(1,len(xy_nbrs2)+1):
            seq = ridge_pts.index([0,inb])
            v1, v2 = vor.ridge_vertices[seq]

            if inb == 1:
                vidxs.append([v1,v2])

            elif inb == 2:
                vidx0 = np.intersect1d(vidxs[0], [v1,v2])[0]
                vidx1 = v1 if vidx0 == v2 else v2
                vidxs[0] = vidx0
                vidxs.append(vidx1)

            else:
                vidx = v1 if vidxs[-1] == v2 else v2
                vidxs.append(vidx)

        xy_vertices = vor.vertices[vidxs]


        return xy_vertices, vor
コード例 #2
0
    def make_dsw_dict_ll2cs(self):
        cs_obj = self.cs_obj
        ll_obj = self.ll_obj

        dsw_dict = dict()       # {dst:[(s,w),(s,w),...],...}
        
        for dst, (rlat,rlon) in enumerate(cs_obj.latlons):
            #print dst
            dst_xy_vertices, vor_obj = cs_obj.get_voronoi(dst)
            dst_poly = Polygon(dst_xy_vertices)

            idx1, idx2, idx3, idx4 = ll_obj.get_surround_idxs(rlat, rlon)
            candidates = set([idx1, idx2, idx3, idx4])
            if -1 in candidates: candidates.remove(-1)
            used_srcs = set()

            dsw_dict[dst] = list()
            while len(candidates) > 0:
                #print '\t', used_srcs
                src = candidates.pop()
                ll_vertices = ll_obj.get_voronoi(src)
                src_xy_vertices = [latlon2xyp(lat,lon,rlat,rlon)[1] \
                                   for lat,lon in ll_vertices]
                src_poly = Polygon(src_xy_vertices)

                ipoly = dst_poly.intersection(src_poly)
                area_ratio = ipoly.area/dst_poly.area

                if area_ratio > 1e-10:
                    dsw_dict[dst].append( (src, area_ratio) )
                    used_srcs.add(src)
                    nbrs = set(ll_obj.get_neighbors(src))
                    candidates.update(nbrs - used_srcs)

        return dsw_dict
コード例 #3
0
    def make_dsw_dict_ll2cs_mpi(self):
        from mpi4py import MPI

        comm = MPI.COMM_WORLD
        nproc = comm.Get_size()
        myrank = comm.Get_rank()

        cs_obj = self.cs_obj
        ll_obj = self.ll_obj
        chunk_size = cs_obj.up_size//nproc//10

        dsw_dict = dict()       # {dst:[(s,w),(s,w),...],...}
        

        if myrank == 0:
            start = 0
            while start < cs_obj.up_size:
                rank = comm.recv(source=MPI.ANY_SOURCE, tag=0)
                comm.send(start, dest=rank, tag=10)
                start += chunk_size

            for i in xrange(nproc-1):
                rank = comm.recv(source=MPI.ANY_SOURCE, tag=0)
                comm.send('quit', dest=rank, tag=10)
                slave_dsw_dict = comm.recv(source=rank, tag=20)
                dsw_dict.update(slave_dsw_dict)

            return dsw_dict

        else:
            while True:
                comm.send(myrank, dest=0, tag=0)
                msg = comm.recv(source=0, tag=10)

                if msg == 'quit':
                    print 'Slave rank %d quit.'%(myrank)
                    comm.send(dsw_dict, dest=0, tag=20)
                    return dsw_dict

                start = msg
                end = start + chunk_size
                end = cs_obj.up_size if end > cs_obj.up_size else end
                print 'rank %d: %d ~ %d'%(myrank, start, end)

                for dst in xrange(start,end):
                    rlat, rlon = cs_obj.latlons[dst]
                    dst_xy_vertices, vor_obj = cs_obj.get_voronoi(dst)
                    dst_poly = Polygon(dst_xy_vertices)

                    idx1, idx2, idx3, idx4 = ll_obj.get_surround_idxs(rlat, rlon)
                    candidates = set([idx1, idx2, idx3, idx4])
                    if -1 in candidates: candidates.remove(-1)
                    used_srcs = set()

                    dsw_dict[dst] = list()
                    while len(candidates) > 0:
                        src = candidates.pop()
                        ll_vertices = ll_obj.get_voronoi(src)
                        src_xy_vertices = [latlon2xyp(lat,lon,rlat,rlon)[1] \
                                           for lat,lon in ll_vertices]
                        src_poly = Polygon(src_xy_vertices)

                        ipoly = dst_poly.intersection(src_poly)
                        area_ratio = ipoly.area/dst_poly.area

                        if area_ratio > 1e-10:
                            dsw_dict[dst].append( (src, area_ratio) )
                            used_srcs.add(src)
                            nbrs = set(ll_obj.get_neighbors(src))
                            candidates.update(nbrs - used_srcs)