Repository: geopandas/geopandas

Issue:
ENH: Add _from_sequence_of_strings for GeometryArray

#### Describe the solution you'd like
Currently passing `dtype={"geometry": "geometry"}` to e.g. `read_csv` fails:
```
import geopandas as gpd
gpd.read_file(gpd.datasets.get_path('nybb')).to_crs("epsg:4326").to_csv("/tmp/boros.csv", index=False)
pd.read_csv("/tmp/boros.csv", dtype={"geometry": "geometry"})
...
NotImplementedError: Extension Array: <class 'geopandas.array.GeometryArray'> must implement _from_sequence_of_strings in order to be used in parser methods
```
It seems like just setting this to call `from_wkt` works fine?
```
gpd.array.GeometryArray._from_sequence_of_strings = gpd.GeoSeries.from_wkt
pd.read_csv("/tmp/boros.csv", dtype={"geometry": "geometry"})
   BoroCode       BoroName  ...    Shape_Area                                           geometry
0         5  Staten Island  ...  1.623820e+09  MULTIPOLYGON (((-74.05050806403247 40.56642203...
1         4         Queens  ...  3.045213e+09  MULTIPOLYGON (((-73.83668274106707 40.59494669...
2         3       Brooklyn  ...  1.937479e+09  MULTIPOLYGON (((-73.86706149472118 40.58208797...
3         1      Manhattan  ...  6.364715e+08  MULTIPOLYGON (((-74.01092841268031 40.68449147...
4         2          Bronx  ...  1.186925e+09  MULTIPOLYGON (((-73.89680883223774 40.79580844...

[5 rows x 5 columns]
```

#### API breaking implications

[this should provide a description of how this feature will affect the API]

#### Describe alternatives you've considered

[this should provide a description of any alternative solutions or features you've considered]

#### Additional context

[add any other context, code examples, or references to existing implementations about the feature request here]

```python
# Your code here, if applicable

```



Discussion:
jorisvandenbossche: I think it would be good to add a small test that reading from CSV with specifying the dtype works (essentially what you did in the issue). While we indeed don't need to test the details of what kind of strings work for `from_wkt`, it's good to have some test to avoid accidentally removing this feature.
bnaul: Makes sense, added!
bnaul: @jorisvandenbossche believe this is ready, I think the test failure is unrelated
martinfleis: Looks good to me! Can you also add a short line to the changelog?
bnaul: @martinfleis done!

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67abca51..e34c157b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,8 @@ New features and improvements:
   output (#3087).
 - `make_valid` option in `overlay` now uses the `make_valid` method instead of
   `buffer(0)` (#3113).
+- Passing `"geometry"` as `dtype` to `pd.read_csv` will now return a GeoSeries for
+  the specified columns (#3101).
 
 Potentially breaking changes:
 - reading a data source that does not have a geometry field using ``read_file``
diff --git a/geopandas/array.py b/geopandas/array.py
index 4017cf15..d1c7104a 100644
--- a/geopandas/array.py
+++ b/geopandas/array.py
@@ -1353,6 +1353,29 @@ class GeometryArray(ExtensionArray):
             scalars = [scalars]
         return from_shapely(scalars)
 
+    @classmethod
+    def _from_sequence_of_strings(cls, strings, *, dtype=None, copy=False):
+        """
+        Construct a new ExtensionArray from a sequence of strings.
+
+        Parameters
+        ----------
+        strings : Sequence
+            Each element will be an instance of the scalar type for this
+            array, ``cls.dtype.type``.
+        dtype : dtype, optional
+            Construct for this particular dtype. This should be a Dtype
+            compatible with the ExtensionArray.
+        copy : bool, default False
+            If True, copy the underlying data.
+
+        Returns
+        -------
+        ExtensionArray
+        """
+        # GH 3099
+        return from_wkt(strings)
+
     def _values_for_factorize(self):
         # type: () -> Tuple[np.ndarray, Any]
         """Return an array and missing value suitable for factorization.


Test patch:
diff --git a/geopandas/io/tests/test_file.py b/geopandas/io/tests/test_file.py
index 22cd2563..4a83e4d2 100644
--- a/geopandas/io/tests/test_file.py
+++ b/geopandas/io/tests/test_file.py
@@ -827,6 +827,15 @@ def test_read_file_missing_geometry(tmpdir, engine):
     assert_frame_equal(df, expected)
 
 
+def test_read_csv_dtype(tmpdir, df_nybb):
+    filename = str(tmpdir / "test.csv")
+
+    df_nybb.to_csv(filename, index=False)
+    pdf = pd.read_csv(filename, dtype={"geometry": "geometry"})
+
+    assert pdf.geometry.dtype == "geometry"
+
+
 def test_read_file__where_filter(engine):
     if FIONA_GE_19 or engine == "pyogrio":
         gdf = geopandas.read_file(