prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Raise error when trying to write empty dataframes
  Currently, the behavior when writing an empty dataframe is counter-intuitive (`ValueError: Geometry column cannot contain mutiple geometry types when writing to file.`). Would it be possible to add  a check and more helpful exception?  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `geopandas/io/file.py`
  Content:
  ```
  1 import os
  2 
  3 import fiona
  4 import numpy as np
  5 import six
  6 
  7 from geopandas import GeoDataFrame
  8 
  9 # Adapted from pandas.io.common
  10 if six.PY3:
  11     from urllib.request import urlopen as _urlopen
  12     from urllib.parse import urlparse as parse_url
  13     from urllib.parse import uses_relative, uses_netloc, uses_params
  14 else:
  15     from urllib2 import urlopen as _urlopen
  16     from urlparse import urlparse as parse_url
  17     from urlparse import uses_relative, uses_netloc, uses_params
  18 
  19 _VALID_URLS = set(uses_relative + uses_netloc + uses_params)
  20 _VALID_URLS.discard('')
  21 
  22 
  23 def _is_url(url):
  24     """Check to see if *url* has a valid protocol."""
  25     try:
  26         return parse_url(url).scheme in _VALID_URLS
  27     except:
  28         return False
  29 
  30 
  31 def read_file(filename, **kwargs):
  32     """
  33     Returns a GeoDataFrame from a file or URL.
  34 
  35     Parameters
  36     ----------
  37     filename: str
  38         Either the absolute or relative path to the file or URL to
  39         be opened.
  40     **kwargs:
  41         Keyword args to be passed to the `open` or `BytesCollection` method
  42         in the fiona library when opening the file. For more information on
  43         possible keywords, type:
  44         ``import fiona; help(fiona.open)``
  45 
  46     Examples
  47     --------
  48     >>> df = geopandas.read_file("nybb.shp")
  49 
  50     Returns
  51     -------
  52     geodataframe : GeoDataFrame
  53     """
  54     bbox = kwargs.pop('bbox', None)
  55     if _is_url(filename):
  56         req = _urlopen(filename)
  57         path_or_bytes = req.read()
  58         reader = fiona.BytesCollection
  59     else:
  60         path_or_bytes = filename
  61         reader = fiona.open
  62 
  63     with reader(path_or_bytes, **kwargs) as features:
  64         crs = features.crs
  65         if bbox is not None:
  66             assert len(bbox) == 4
  67             f_filt = features.filter(bbox=bbox)
  68         else:
  69             f_filt = features
  70 
  71         columns = list(features.meta["schema"]["properties"]) + ["geometry"]
  72         gdf = GeoDataFrame.from_features(f_filt, crs=crs, columns=columns)
  73 
  74     return gdf
  75 
  76 
  77 def to_file(df, filename, driver="ESRI Shapefile", schema=None,
  78             **kwargs):
  79     """
  80     Write this GeoDataFrame to an OGR data source
  81 
  82     A dictionary of supported OGR providers is available via:
  83     >>> import fiona
  84     >>> fiona.supported_drivers
  85 
  86     Parameters
  87     ----------
  88     df : GeoDataFrame to be written
  89     filename : string
  90         File path or file handle to write to.
  91     driver : string, default 'ESRI Shapefile'
  92         The OGR format driver used to write the vector file.
  93     schema : dict, default None
  94         If specified, the schema dictionary is passed to Fiona to
  95         better control how the file is written. If None, GeoPandas
  96         will determine the schema based on each column's dtype
  97 
  98     The *kwargs* are passed to fiona.open and can be used to write
  99     to multi-layer data, store data within archives (zip files), etc.
  100     """
  101     if schema is None:
  102         schema = infer_schema(df)
  103     filename = os.path.abspath(os.path.expanduser(filename))
  104     with fiona.drivers():
  105         with fiona.open(filename, 'w', driver=driver, crs=df.crs,
  106                         schema=schema, **kwargs) as colxn:
  107             colxn.writerecords(df.iterfeatures())
  108 
  109 
  110 def infer_schema(df):
  111     try:
  112         from collections import OrderedDict
  113     except ImportError:
  114         from ordereddict import OrderedDict
  115 
  116     def convert_type(column, in_type):
  117         if in_type == object:
  118             return 'str'
  119         out_type = type(np.asscalar(np.zeros(1, in_type))).__name__
  120         if out_type == 'long':
  121             out_type = 'int'
  122         if out_type == 'bool':
  123             raise ValueError('column "{}" is boolean type, '.format(column) +
  124                              'which is unsupported in file writing. '
  125                              'Consider casting the column to int type.')
  126         return out_type
  127 
  128     properties = OrderedDict([
  129         (col, convert_type(col, _type)) for col, _type in
  130         zip(df.columns, df.dtypes) if col != df._geometry_column_name
  131     ])
  132 
  133     geom_type = _common_geom_type(df)
  134     if not geom_type:
  135         raise ValueError("Geometry column cannot contain mutiple "
  136                          "geometry types when writing to file.")
  137 
  138     schema = {'geometry': geom_type, 'properties': properties}
  139 
  140     return schema
  141 
  142 
  143 def _common_geom_type(df):
  144     # Need to check geom_types before we write to file...
  145     # Some (most?) providers expect a single geometry type:
  146     # Point, LineString, or Polygon
  147     geom_types = df.geometry.geom_type.unique()
  148 
  149     from os.path import commonprefix
  150     # use reversed geom types and commonprefix to find the common suffix,
  151     # then reverse the result to get back to a geom type
  152     geom_type = commonprefix([g[::-1] for g in geom_types if g])[::-1]
  153     if not geom_type:
  154         return None
  155 
  156     if df.geometry.has_z.any():
  157         geom_type = "3D " + geom_type
  158 
  159     return geom_type
  160
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/geopandas/io/file.py b/geopandas/io/file.py
  --- a/geopandas/io/file.py
  +++ b/geopandas/io/file.py
  @@ -130,7 +130,11 @@
           zip(df.columns, df.dtypes) if col != df._geometry_column_name
       ])
   
  +    if df.empty:
  +        raise ValueError("Cannot write empty DataFrame to file.")
  +
       geom_type = _common_geom_type(df)
  +    
       if not geom_type:
           raise ValueError("Geometry column cannot contain mutiple "
                            "geometry types when writing to file.")
  
verification_info: {"golden_diff": "diff --git a/geopandas/io/file.py b/geopandas/io/file.py\n--- a/geopandas/io/file.py\n+++ b/geopandas/io/file.py\n@@ -130,7 +130,11 @@\n         zip(df.columns, df.dtypes) if col != df._geometry_column_name\n     ])\n \n+    if df.empty:\n+        raise ValueError(\"Cannot write empty DataFrame to file.\")\n+\n     geom_type = _common_geom_type(df)\n+    \n     if not geom_type:\n         raise ValueError(\"Geometry column cannot contain mutiple \"\n                          \"geometry types when writing to file.\")\n", "issue": "Raise error when trying to write empty dataframes\nCurrently, the behavior when writing an empty dataframe is counter-intuitive (`ValueError: Geometry column cannot contain mutiple geometry types when writing to file.`). Would it be possible to add  a check and more helpful exception?  \n", "before_files": [{"content": "import os\n\nimport fiona\nimport numpy as np\nimport six\n\nfrom geopandas import GeoDataFrame\n\n# Adapted from pandas.io.common\nif six.PY3:\n    from urllib.request import urlopen as _urlopen\n    from urllib.parse import urlparse as parse_url\n    from urllib.parse import uses_relative, uses_netloc, uses_params\nelse:\n    from urllib2 import urlopen as _urlopen\n    from urlparse import urlparse as parse_url\n    from urlparse import uses_relative, uses_netloc, uses_params\n\n_VALID_URLS = set(uses_relative + uses_netloc + uses_params)\n_VALID_URLS.discard('')\n\n\ndef _is_url(url):\n    \"\"\"Check to see if *url* has a valid protocol.\"\"\"\n    try:\n        return parse_url(url).scheme in _VALID_URLS\n    except:\n        return False\n\n\ndef read_file(filename, **kwargs):\n    \"\"\"\n    Returns a GeoDataFrame from a file or URL.\n\n    Parameters\n    ----------\n    filename: str\n        Either the absolute or relative path to the file or URL to\n        be opened.\n    **kwargs:\n        Keyword args to be passed to the `open` or `BytesCollection` method\n        in the fiona library when opening the file. For more information on\n        possible keywords, type:\n        ``import fiona; help(fiona.open)``\n\n    Examples\n    --------\n    >>> df = geopandas.read_file(\"nybb.shp\")\n\n    Returns\n    -------\n    geodataframe : GeoDataFrame\n    \"\"\"\n    bbox = kwargs.pop('bbox', None)\n    if _is_url(filename):\n        req = _urlopen(filename)\n        path_or_bytes = req.read()\n        reader = fiona.BytesCollection\n    else:\n        path_or_bytes = filename\n        reader = fiona.open\n\n    with reader(path_or_bytes, **kwargs) as features:\n        crs = features.crs\n        if bbox is not None:\n            assert len(bbox) == 4\n            f_filt = features.filter(bbox=bbox)\n        else:\n            f_filt = features\n\n        columns = list(features.meta[\"schema\"][\"properties\"]) + [\"geometry\"]\n        gdf = GeoDataFrame.from_features(f_filt, crs=crs, columns=columns)\n\n    return gdf\n\n\ndef to_file(df, filename, driver=\"ESRI Shapefile\", schema=None,\n            **kwargs):\n    \"\"\"\n    Write this GeoDataFrame to an OGR data source\n\n    A dictionary of supported OGR providers is available via:\n    >>> import fiona\n    >>> fiona.supported_drivers\n\n    Parameters\n    ----------\n    df : GeoDataFrame to be written\n    filename : string\n        File path or file handle to write to.\n    driver : string, default 'ESRI Shapefile'\n        The OGR format driver used to write the vector file.\n    schema : dict, default None\n        If specified, the schema dictionary is passed to Fiona to\n        better control how the file is written. If None, GeoPandas\n        will determine the schema based on each column's dtype\n\n    The *kwargs* are passed to fiona.open and can be used to write\n    to multi-layer data, store data within archives (zip files), etc.\n    \"\"\"\n    if schema is None:\n        schema = infer_schema(df)\n    filename = os.path.abspath(os.path.expanduser(filename))\n    with fiona.drivers():\n        with fiona.open(filename, 'w', driver=driver, crs=df.crs,\n                        schema=schema, **kwargs) as colxn:\n            colxn.writerecords(df.iterfeatures())\n\n\ndef infer_schema(df):\n    try:\n        from collections import OrderedDict\n    except ImportError:\n        from ordereddict import OrderedDict\n\n    def convert_type(column, in_type):\n        if in_type == object:\n            return 'str'\n        out_type = type(np.asscalar(np.zeros(1, in_type))).__name__\n        if out_type == 'long':\n            out_type = 'int'\n        if out_type == 'bool':\n            raise ValueError('column \"{}\" is boolean type, '.format(column) +\n                             'which is unsupported in file writing. '\n                             'Consider casting the column to int type.')\n        return out_type\n\n    properties = OrderedDict([\n        (col, convert_type(col, _type)) for col, _type in\n        zip(df.columns, df.dtypes) if col != df._geometry_column_name\n    ])\n\n    geom_type = _common_geom_type(df)\n    if not geom_type:\n        raise ValueError(\"Geometry column cannot contain mutiple \"\n                         \"geometry types when writing to file.\")\n\n    schema = {'geometry': geom_type, 'properties': properties}\n\n    return schema\n\n\ndef _common_geom_type(df):\n    # Need to check geom_types before we write to file...\n    # Some (most?) providers expect a single geometry type:\n    # Point, LineString, or Polygon\n    geom_types = df.geometry.geom_type.unique()\n\n    from os.path import commonprefix\n    # use reversed geom types and commonprefix to find the common suffix,\n    # then reverse the result to get back to a geom type\n    geom_type = commonprefix([g[::-1] for g in geom_types if g])[::-1]\n    if not geom_type:\n        return None\n\n    if df.geometry.has_z.any():\n        geom_type = \"3D \" + geom_type\n\n    return geom_type\n", "path": "geopandas/io/file.py"}], "after_files": [{"content": "import os\n\nimport fiona\nimport numpy as np\nimport six\n\nfrom geopandas import GeoDataFrame\n\n# Adapted from pandas.io.common\nif six.PY3:\n    from urllib.request import urlopen as _urlopen\n    from urllib.parse import urlparse as parse_url\n    from urllib.parse import uses_relative, uses_netloc, uses_params\nelse:\n    from urllib2 import urlopen as _urlopen\n    from urlparse import urlparse as parse_url\n    from urlparse import uses_relative, uses_netloc, uses_params\n\n_VALID_URLS = set(uses_relative + uses_netloc + uses_params)\n_VALID_URLS.discard('')\n\n\ndef _is_url(url):\n    \"\"\"Check to see if *url* has a valid protocol.\"\"\"\n    try:\n        return parse_url(url).scheme in _VALID_URLS\n    except:\n        return False\n\n\ndef read_file(filename, **kwargs):\n    \"\"\"\n    Returns a GeoDataFrame from a file or URL.\n\n    Parameters\n    ----------\n    filename: str\n        Either the absolute or relative path to the file or URL to\n        be opened.\n    **kwargs:\n        Keyword args to be passed to the `open` or `BytesCollection` method\n        in the fiona library when opening the file. For more information on\n        possible keywords, type:\n        ``import fiona; help(fiona.open)``\n\n    Examples\n    --------\n    >>> df = geopandas.read_file(\"nybb.shp\")\n\n    Returns\n    -------\n    geodataframe : GeoDataFrame\n    \"\"\"\n    bbox = kwargs.pop('bbox', None)\n    if _is_url(filename):\n        req = _urlopen(filename)\n        path_or_bytes = req.read()\n        reader = fiona.BytesCollection\n    else:\n        path_or_bytes = filename\n        reader = fiona.open\n\n    with reader(path_or_bytes, **kwargs) as features:\n        crs = features.crs\n        if bbox is not None:\n            assert len(bbox) == 4\n            f_filt = features.filter(bbox=bbox)\n        else:\n            f_filt = features\n\n        columns = list(features.meta[\"schema\"][\"properties\"]) + [\"geometry\"]\n        gdf = GeoDataFrame.from_features(f_filt, crs=crs, columns=columns)\n\n    return gdf\n\n\ndef to_file(df, filename, driver=\"ESRI Shapefile\", schema=None,\n            **kwargs):\n    \"\"\"\n    Write this GeoDataFrame to an OGR data source\n\n    A dictionary of supported OGR providers is available via:\n    >>> import fiona\n    >>> fiona.supported_drivers\n\n    Parameters\n    ----------\n    df : GeoDataFrame to be written\n    filename : string\n        File path or file handle to write to.\n    driver : string, default 'ESRI Shapefile'\n        The OGR format driver used to write the vector file.\n    schema : dict, default None\n        If specified, the schema dictionary is passed to Fiona to\n        better control how the file is written. If None, GeoPandas\n        will determine the schema based on each column's dtype\n\n    The *kwargs* are passed to fiona.open and can be used to write\n    to multi-layer data, store data within archives (zip files), etc.\n    \"\"\"\n    if schema is None:\n        schema = infer_schema(df)\n    filename = os.path.abspath(os.path.expanduser(filename))\n    with fiona.drivers():\n        with fiona.open(filename, 'w', driver=driver, crs=df.crs,\n                        schema=schema, **kwargs) as colxn:\n            colxn.writerecords(df.iterfeatures())\n\n\ndef infer_schema(df):\n    try:\n        from collections import OrderedDict\n    except ImportError:\n        from ordereddict import OrderedDict\n\n    def convert_type(column, in_type):\n        if in_type == object:\n            return 'str'\n        out_type = type(np.asscalar(np.zeros(1, in_type))).__name__\n        if out_type == 'long':\n            out_type = 'int'\n        if out_type == 'bool':\n            raise ValueError('column \"{}\" is boolean type, '.format(column) +\n                             'which is unsupported in file writing. '\n                             'Consider casting the column to int type.')\n        return out_type\n\n    properties = OrderedDict([\n        (col, convert_type(col, _type)) for col, _type in\n        zip(df.columns, df.dtypes) if col != df._geometry_column_name\n    ])\n\n    if df.empty:\n        raise ValueError(\"Cannot write empty DataFrame to file.\")\n\n    geom_type = _common_geom_type(df)\n    \n    if not geom_type:\n        raise ValueError(\"Geometry column cannot contain mutiple \"\n                         \"geometry types when writing to file.\")\n\n    schema = {'geometry': geom_type, 'properties': properties}\n\n    return schema\n\n\ndef _common_geom_type(df):\n    # Need to check geom_types before we write to file...\n    # Some (most?) providers expect a single geometry type:\n    # Point, LineString, or Polygon\n    geom_types = df.geometry.geom_type.unique()\n\n    from os.path import commonprefix\n    # use reversed geom types and commonprefix to find the common suffix,\n    # then reverse the result to get back to a geom type\n    geom_type = commonprefix([g[::-1] for g in geom_types if g])[::-1]\n    if not geom_type:\n        return None\n\n    if df.geometry.has_z.any():\n        geom_type = \"3D \" + geom_type\n\n    return geom_type\n", "path": "geopandas/io/file.py"}]}