Exemplo n.º 1
0
def test_polygon_interiors():
    
    ax = plt.subplot(211, projection=ccrs.PlateCarree())
    ax.coastlines()    
    ax.set_global() # XXX could be the default???
   
    pth = Path([[0, 45], [60, 45], [60, -45], [0, -45], [0, -45], 
                [10, 20], [10, -20], [40, -20], [40, 20], [10, -20]], 
               [1, 2, 2, 2, 79, 1, 2, 2 , 2, 79])
    
    patches_native = []
    patches = []
    for geos in cpatch.path_to_geos(pth):
        for pth in cpatch.geos_to_path(geos):
            patches.append(mpatches.PathPatch(pth))
        
        # buffer by 10 degrees (leaves a small hole in the middle)
        geos_buffered = geos.buffer(10)
        for pth in cpatch.geos_to_path(geos_buffered):
            patches_native.append(mpatches.PathPatch(pth))
    
    collection = PatchCollection(patches_native, facecolor='red', alpha=0.4,
                                 transform=ax.projection
                                 )
    ax.add_collection(collection)

    collection = PatchCollection(patches, facecolor='yellow', alpha=0.4,
                                 transform=ccrs.Geodetic()
                                 )
    
    ax.add_collection(collection)
    
    
    # test multiple interior polygons
    ax = plt.subplot(212, projection=ccrs.PlateCarree(), xlim=[-5, 15], ylim=[-5, 15])
    ax.coastlines()
    
    exterior = np.array(shapely.geometry.box(0, 0, 12, 12).exterior.coords)
    interiors = [
                 np.array(shapely.geometry.box(1, 1, 2, 2, ccw=False).exterior.coords),
                 np.array(shapely.geometry.box(1, 8, 2, 9, ccw=False).exterior.coords),
                 ]

    poly = shapely.geometry.Polygon(exterior, interiors)
    
    patches = []
    for pth in cpatch.geos_to_path(poly):
        patches.append(mpatches.PathPatch(pth))
    
    collection = PatchCollection(patches, facecolor='yellow', alpha=0.4,
                                 transform=ccrs.Geodetic()
                                 )
    ax.add_collection(collection)
Exemplo n.º 2
0
def test_polygon_interiors():
    
    ax = plt.subplot(211, projection=ccrs.PlateCarree())
    ax.coastlines()    
    ax.set_global() # XXX could be the default???
   
    pth = Path([[0, 45], [60, 45], [60, -45], [0, -45], [0, -45], 
                [10, 20], [10, -20], [40, -20], [40, 20], [10, -20]], 
               [1, 2, 2, 2, 79, 1, 2, 2 , 2, 79])
    
    patches_native = []
    patches = []
    for geos in cpatch.path_to_geos(pth):
        for pth in cpatch.geos_to_path(geos):
            patches.append(mpatches.PathPatch(pth))
        
        # buffer by 10 degrees (leaves a small hole in the middle)
        geos_buffered = geos.buffer(10)
        for pth in cpatch.geos_to_path(geos_buffered):
            patches_native.append(mpatches.PathPatch(pth))
    
    collection = PatchCollection(patches_native, facecolor='red', alpha=0.4,
                                 transform=ax.projection
                                 )
    ax.add_collection(collection)

    collection = PatchCollection(patches, facecolor='yellow', alpha=0.4,
                                 transform=ccrs.Geodetic()
                                 )
    
    ax.add_collection(collection)
    
    
    # test multiple interior polygons
    ax = plt.subplot(212, projection=ccrs.PlateCarree(), xlim=[-5, 15], ylim=[-5, 15])
    ax.coastlines()
    
    exterior = np.array(shapely.geometry.box(0, 0, 12, 12).exterior.coords)
    interiors = [
                 np.array(shapely.geometry.box(1, 1, 2, 2, ccw=False).exterior.coords),
                 np.array(shapely.geometry.box(1, 8, 2, 9, ccw=False).exterior.coords),
                 ]

    poly = shapely.geometry.Polygon(exterior, interiors)
    
    patches = []
    for pth in cpatch.geos_to_path(poly):
        patches.append(mpatches.PathPatch(pth))
    
    collection = PatchCollection(patches, facecolor='yellow', alpha=0.4,
                                 transform=ccrs.Geodetic()
                                 )
    ax.add_collection(collection)
Exemplo n.º 3
0
    def transform_path_non_affine(self, path):
        bypass = self.source_projection == self.target_projection
        if bypass:
            projection = self.source_projection
            if isinstance(projection, ccrs._CylindricalProjection):
                x = path.vertices[:, 0]
                x_limits = projection.x_limits
                bypass = x.min() >= x_limits[0] and x.max() <= x_limits[1]
        if bypass:
            return path

        if path.vertices.shape == (1, 2):
            return mpath.Path(self.transform(path.vertices))

        transformed_geoms = []
        for geom in patch.path_to_geos(path):
            transformed_geoms.append(self.target_projection.project_geometry(geom, self.source_projection))

        if not transformed_geoms:
            return mpath.Path(numpy.empty([0, 2]))
        else:
            paths = patch.geos_to_path(transformed_geoms)
            if not paths:
                return mpath.Path(numpy.empty([0, 2]))
            points, codes = zip(*[patch.path_segments(path, curves=False, simplify=False) for path in paths])
            return mpath.Path(numpy.concatenate(points, 0), numpy.concatenate(codes))
Exemplo n.º 4
0
    def gshhs_line(self, outline_color='k', domain=None, resolution='low', **kwargs):
        # domain is a shapely geometry (Polygon or MultiPolygon)
        import cartopy.gshhs as gshhs
#        import cartopy.spherical as spherical
        from matplotlib.collections import PatchCollection, LineCollection

        paths = []

        projection = self.projection

        if domain is None:
            domain = self.map_domain(ccrs.PlateCarree())

        for points in gshhs.read_gshhc(gshhs.fnames[resolution], poly=False, domain=domain):
            paths.extend(patch.geos_to_path(shapely.geometry.LineString(points)))

#            slinestring = shapely.geometry.LineString(points)
#            projected = projection.project_geometry(slinestring)            
#            paths.extend(patch.geos_to_path(projected))

        collection = PatchCollection([mpatches.PathPatch(pth) for pth in paths],
                             edgecolor=outline_color, facecolor='none',
                             transform=ccrs.PlateCarree(),
                             **kwargs
                             )

        self.add_collection(collection, autolim=False)
Exemplo n.º 5
0
 def ll_boundary_poly_draw(self):
     for path in patch.geos_to_path(self.ll_boundary_poly()):
     # XXX Seems like great circle interpolation is making the plot strange...
         pp = mpatches.PathPatch(path, color='red', transform=cartopy.prj.PlateCarree(), alpha=0.5)
         dl = self.viewLim.get_points().copy()
         self.add_patch(pp)
         self.viewLim.set_points(dl)
Exemplo n.º 6
0
    def gshhs(self, outline_color='k', land_fill='green', ocean_fill='None', resolution='coarse', domain=None):
        import cartopy.gshhs as gshhs
        from matplotlib.collections import PatchCollection

        if ocean_fill is not None and land_fill is None:
            land_fill = self.outline_patch.get_facecolor()

        if domain is None:
            domain = self.ll_boundary_poly()

        paths = []
        for points in gshhs.read_gshhc(gshhs.fnames[resolution], poly=True, domain=domain):
            # XXX Sometimes we only want to do lines...
            poly = shapely.geometry.Polygon(points[::-1, :])
            projected = self.projection.project_polygon(poly)

            paths.extend(patch.geos_to_path(projected))

        if ocean_fill is not None:
            self.outline_patch.set_facecolor(ocean_fill)

        collection = PatchCollection([mpatches.PathPatch(pth) for pth in paths],
                                     edgecolor=outline_color,
                                     facecolor=land_fill,
                                     zorder=2,
                                     )
        # XXX Should it update the limits??? (AND HOW???)
        self.add_collection(collection)
Exemplo n.º 7
0
    def transform_path_non_affine(self, src_path):
        """
        Transforms from source to target coordinates.
        
        Caches results, so subsequent calls with the same *src_path* argument
        (and the same source and target projections) are faster.
        
        Args:
        
            * src_path - A matplotlib :class:`~matplotlib.path.Path` object with
                     vertices in source coordinates.
            
        Returns
        
            * A matplotlib :class:`~matplotlib.path.Path` with vertices
              in target coordinates.
            
        """
        mapping = _PATH_TRANSFORM_CACHE.get(src_path)
        if mapping is not None:
            key = (self.source_projection, self.target_projection)
            result = mapping.get(key)
            if result is not None:
                return result
        
        bypass = self.source_projection == self.target_projection
        if bypass:
            projection = self.source_projection
            if isinstance(projection, ccrs._CylindricalProjection):
                x = src_path.vertices[:, 0]
                x_limits = projection.x_limits
                bypass = x.min() >= x_limits[0] and x.max() <= x_limits[1]
        if bypass:
            return src_path

        if src_path.vertices.shape == (1, 2):
            return mpath.Path(self.transform(src_path.vertices))

        transformed_geoms = []
        for geom in patch.path_to_geos(src_path):
            transformed_geoms.append(self.target_projection.project_geometry(geom, self.source_projection))

        if not transformed_geoms:
            result = mpath.Path(numpy.empty([0, 2]))
        else:
            paths = patch.geos_to_path(transformed_geoms)
            if not paths:
                return mpath.Path(numpy.empty([0, 2]))
            points, codes = zip(*[patch.path_segments(path, curves=False, simplify=False) for path in paths])
            result = mpath.Path(numpy.concatenate(points, 0), numpy.concatenate(codes))
        
        # store the result in the cache for future performance boosts    
        key = (self.source_projection, self.target_projection)
        if mapping is None:
            _PATH_TRANSFORM_CACHE[src_path] = {key: result}
        else:
            mapping[key] = result
        
        return result
Exemplo n.º 8
0
def mpl_axes_plot(axes, geometries, **kwargs):
    """Plot lines on the given axes, given the geometries."""
    # TODO: This interface should be exposed nicely on the geoaxes itself.
    import matplotlib.collections as mcollections
    import cartopy.mpl_integration.patch as patch

    paths = []
    for geom in geometries:
        paths.extend(patch.geos_to_path(axes.projection.project_geometry(geom)))
    axes.add_collection(mcollections.PathCollection(paths, facecolor='none', **kwargs), autolim=False)
def draw_polygon(projection, polygon, color=None):
    multi_polygon = projection.project_geometry(polygon)
    for polygon in multi_polygon:
        #plt.plot(*zip(*polygon.exterior.coords), marker='+', color=color)
        #_arrows(projection, polygon.exterior)
        #continue
        import cartopy.mpl_integration.patch as patch
        paths = patch.geos_to_path(polygon)
        for pth in paths:
            patch = mpatches.PathPatch(pth, edgecolor='none', alpha=0.5, facecolor=color, lw=0)
            plt.gca().add_patch(patch)
Exemplo n.º 10
0
    def coastlines_land(self, facecolor=colors['land'], **kwargs):
        import cartopy.io.shapereader as shapereader

        land_path = shapereader.natural_earth(resolution='110m',
                                               category='physical',
                                               name='land')

        paths = []
        for geom in shapereader.Reader(land_path).geometries():

            paths.extend(patch.geos_to_path(self.projection.project_geometry(geom)))
        self.add_collection(mcollections.PathCollection(paths, facecolor=facecolor, **kwargs), autolim=False)
Exemplo n.º 11
0
def show(projection, geometry):
    if geometry.type == 'MultiPolygon' and 1:
        multi_polygon = geometry
        for polygon in multi_polygon:
            import cartopy.mpl_integration.patch as patch
            paths = patch.geos_to_path(polygon)
            for pth in paths:
                patch = mpatches.PathPatch(pth,
                                           edgecolor='none',
                                           lw=0,
                                           alpha=0.2)
                plt.gca().add_patch(patch)
            line_string = polygon.exterior
            plt.plot(*zip(*line_string.coords), marker='+', linestyle='-')
    elif geometry.type == 'MultiPolygon':
        multi_polygon = geometry
        for polygon in multi_polygon:
            line_string = polygon.exterior
            plt.plot(*zip(*line_string.coords), marker='+', linestyle='-')

    elif geometry.type == 'MultiLineString':
        multi_line_string = geometry
        for line_string in multi_line_string:
            plt.plot(*zip(*line_string.coords), marker='+', linestyle='-')

    if 1:
        # Whole map domain
        plt.autoscale()
    elif 0:
        # The left-hand triangle
        plt.xlim(-1.65e7, -1.2e7)
        plt.ylim(0.3e7, 0.65e7)
    elif 0:
        # The tip of the left-hand triangle
        plt.xlim(-1.65e7, -1.55e7)
        plt.ylim(0.3e7, 0.4e7)
    elif 1:
        # The very tip of the left-hand triangle
        plt.xlim(-1.632e7, -1.622e7)
        plt.ylim(0.327e7, 0.337e7)
    elif 1:
        # The tip of the right-hand triangle
        plt.xlim(1.55e7, 1.65e7)
        plt.ylim(0.3e7, 0.4e7)

    plt.plot(*zip(*projection.boundary.coords),
             marker='o',
             scalex=False,
             scaley=False,
             zorder=-1)

    plt.show()
Exemplo n.º 12
0
    def transform_path_non_affine(self, path):
        if path.vertices.shape == (1, 2):
            return mpath.Path(self.transform(path.vertices))

        transformed_geoms = []
        for geom in patch.path_to_geos(path):
            transformed_geoms.append(self.target_projection.project_geometry(geom, self.source_projection))

        if not transformed_geoms:
            return mpath.Path(numpy.empty([0, 2]))
        else:
            paths = patch.geos_to_path(transformed_geoms)
            if not paths:
                return mpath.Path(numpy.empty([0, 2]))
            points, codes = zip(*[patch.path_segments(path, curves=False, simplify=False) for path in paths])
            return mpath.Path(numpy.concatenate(points, 0), numpy.concatenate(codes))
Exemplo n.º 13
0
def show(projection, geometry):
    if geometry.type == 'MultiPolygon' and 1:
        multi_polygon = geometry
        for polygon in multi_polygon:
            import cartopy.mpl_integration.patch as patch
            paths = patch.geos_to_path(polygon)
            for pth in paths:
                patch = mpatches.PathPatch(pth, edgecolor='none', lw=0, alpha=0.2)
                plt.gca().add_patch(patch)
            line_string = polygon.exterior
            plt.plot(*zip(*line_string.coords), marker='+', linestyle='-')
    elif geometry.type == 'MultiPolygon':
        multi_polygon = geometry
        for polygon in multi_polygon:
            line_string = polygon.exterior
            plt.plot(*zip(*line_string.coords), marker='+', linestyle='-')

    elif geometry.type == 'MultiLineString':
        multi_line_string = geometry
        for line_string in multi_line_string:
            plt.plot(*zip(*line_string.coords), marker='+', linestyle='-')

    if 1:
        # Whole map domain
        plt.autoscale()
    elif 0:
        # The left-hand triangle
        plt.xlim(-1.65e7, -1.2e7)
        plt.ylim(0.3e7, 0.65e7)
    elif 0:
        # The tip of the left-hand triangle
        plt.xlim(-1.65e7, -1.55e7)
        plt.ylim(0.3e7, 0.4e7)
    elif 1:
        # The very tip of the left-hand triangle
        plt.xlim(-1.632e7, -1.622e7)
        plt.ylim(0.327e7, 0.337e7)
    elif 1:
        # The tip of the right-hand triangle
        plt.xlim(1.55e7, 1.65e7)
        plt.ylim(0.3e7, 0.4e7)

    plt.plot(*zip(*projection.boundary.coords), marker='o', scalex=False, scaley=False, zorder=-1)

    plt.show()
Exemplo n.º 14
0
    def _boundary(self):
        """
        Adds the map's boundary.
        
        Note:
        
            The boundary is not the axes.patch, which provides rectilinear 
            clipping for all of the map's artists.
        
        The axes.patch will have its visibility set to False inside GeoAxes.gca()
        """
        import cartopy.mpl_integration.patch as p
        path, = p.geos_to_path(self.projection.boundary)

#        from matplotlib.collections import PatchCollection

        self.sct = sct = SimpleClippedTransform(self.transScale + self.transLimits, self.transAxes)

        # XXX Should be exactly one path...
        collection = mpatches.PathPatch(path,
                                        facecolor='none', edgecolor='k', zorder=1000,
#                                        transform=self.transData,
                                        transform=sct, clip_on=False,
                                        )
        self.outline_patch = collection
        # XXX autolim = False
        self.add_patch(collection)

        # put a color patch for background color
        # XXX Should be exactly one path...
        collection = mpatches.PathPatch(path,
                                        facecolor='w', edgecolor='none', zorder= -1,
                                        transform=sct, clip_on=False,
                                        )
        self.background_patch = collection
        # XXX autolim = False
        self.add_patch(collection)


        self.patch.set_facecolor((1, 1, 1, 0))
        self.patch.set_edgecolor((0.5, 0.5, 0.5))
        self.patch.set_linewidth(0.0)
Exemplo n.º 15
0
    def add_geometries(self, geoms, crs, **collection_kwargs):
        """
        Add the given shapely geometries (in the given crs) to the axes as 
        a :class:`~matplotlib.collections.PathCollection`.
        
        """
        paths = []
        key = (crs, self.projection)
        for geom in geoms:
            mapping = _GEOMETRY_TO_PATH_CACHE.setdefault(geom, {})
            geom_paths = mapping.get(key)
            if geom_paths is None:
                projected = self.projection.project_geometry(geom, crs)
                geom_paths = patch.geos_to_path(projected)
                mapping[key] = geom_paths
            paths.extend(geom_paths)

        c = mcollections.PathCollection(paths, transform=self.projection,
                                        **collection_kwargs)
        self.add_collection(c, autolim=False)
        
        return c
Exemplo n.º 16
0
    def _boundary(self):
        """
        Adds the map's boundary. Note, the boundary is not the axes.patch, which provides rectilinear 
        clipping for all of the map's artists.
        The axes.patch will have its visibility set to False inside GeoAxes.gca()
        """
        import cartopy.mpl_integration.patch as p
        path, = p.geos_to_path(self.projection.boundary)

#        from matplotlib.collections import PatchCollection

        self.sct = sct = SimpleClippedTransform(self.transScale + self.transLimits, self.transAxes)
        self.smt = SimpleMaskingTransform(self.transScale + self.transLimits, self.transAxes)

        # XXX Should be exactly one path...
        collection = mpatches.PathPatch(path,
                                        facecolor='none', edgecolor='k', zorder=1000,
#                                        transform=self.transData,
                                        transform=sct, clip_on=False,
                                        )
        self.outline_patch = collection
        # XXX autolim = False
        self.add_patch(collection)

        # put a color patch for background color
        # XXX Should be exactly one path...
        collection = mpatches.PathPatch(path,
                                        facecolor='w', edgecolor='none', zorder= -1,
                                        transform=sct, clip_on=False,
                                        )
        self.background_patch = collection
        # XXX autolim = False
        self.add_patch(collection)


        self.patch.set_facecolor((1, 1, 1, 0))
        self.patch.set_edgecolor((0.5, 0.5, 0.5))
        self.patch.set_linewidth(0.0)