-
Notifications
You must be signed in to change notification settings - Fork 902
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
162 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import pandas as pd | ||
import geopandas as gpd | ||
from shapely.geometry import ( | ||
Point, | ||
LineString, | ||
Polygon, | ||
MultiPoint, | ||
MultiLineString, | ||
MultiPolygon | ||
) | ||
from shapely.geometry.base import BaseGeometry | ||
|
||
_multi_type_map = { | ||
'Point': MultiPoint, | ||
'LineString': MultiLineString, | ||
'Polygon': MultiPolygon | ||
} | ||
|
||
def collect(x, multi=False): | ||
""" | ||
Collect single part geometries into their Multi* counterpart | ||
Parameters | ||
---------- | ||
x : an iterable or Series of Shapely geometries, a GeoSeries, or | ||
a single Shapely geometry | ||
multi : boolean, default False | ||
if True, force returned geometries to be Multi* even if they | ||
only have one component. | ||
""" | ||
if isinstance(x, BaseGeometry): | ||
x = [x] | ||
elif isinstance(x, pd.Series): | ||
x = list(x) | ||
|
||
# We cannot create GeometryCollection here so all types | ||
# must be the same. If there is more than one element, | ||
# they cannot be Multi*, i.e., can't pass in combination of | ||
# Point and MultiPoint... or even just MultiPoint | ||
t = x[0].type | ||
if not all(g.type == t for g in x): | ||
raise ValueError('Geometry type must be homogenous') | ||
if len(x) > 1 and t.startswith('Multi'): | ||
raise ValueError( | ||
'Cannot collect {0}. Must have single geometries'.format(t)) | ||
|
||
if len(x) == 1 and (t.startswith('Multi') or not multi): | ||
# If there's only one single part geom and we're not forcing to | ||
# multi, then just return it | ||
return x[0] | ||
return _multi_type_map[t](x) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from __future__ import absolute_import | ||
from shapely.geometry import Point, MultiPoint, LineString | ||
from geopandas import GeoSeries | ||
from geopandas.tools import collect | ||
from .util import unittest | ||
|
||
class TestTools(unittest.TestCase): | ||
def setUp(self): | ||
self.p1 = Point(0,0) | ||
self.p2 = Point(1,1) | ||
self.p3 = Point(2,2) | ||
self.mpc = MultiPoint([self.p1, self.p2, self.p3]) | ||
|
||
self.mp1 = MultiPoint([self.p1, self.p2]) | ||
self.line1 = LineString([(3,3), (4,4)]) | ||
|
||
def test_collect_single(self): | ||
result = collect(self.p1) | ||
self.assert_(self.p1.equals(result)) | ||
|
||
def test_collect_single_force_multi(self): | ||
result = collect(self.p1, multi=True) | ||
expected = MultiPoint([self.p1]) | ||
self.assert_(expected.equals(result)) | ||
|
||
def test_collect_multi(self): | ||
result = collect(self.mp1) | ||
self.assert_(self.mp1.equals(result)) | ||
|
||
def test_collect_multi_force_multi(self): | ||
result = collect(self.mp1) | ||
self.assert_(self.mp1.equals(result)) | ||
|
||
def test_collect_list(self): | ||
result = collect([self.p1, self.p2, self.p3]) | ||
self.assert_(self.mpc.equals(result)) | ||
|
||
def test_collect_GeoSeries(self): | ||
s = GeoSeries([self.p1, self.p2, self.p3]) | ||
result = collect(s) | ||
self.assert_(self.mpc.equals(result)) | ||
|
||
def test_collect_mixed_types(self): | ||
with self.assertRaises(ValueError): | ||
collect([self.p1, self.line1]) | ||
|
||
def test_collect_mixed_multi(self): | ||
with self.assertRaises(ValueError): | ||
collect([self.mpc, self.mp1]) |