Non-planar enforced touches#
import geopandas
import numpy
import matplotlib.pyplot as plt
import geoplanar
import libpysal
from shapely.geometry import Polygon
c1 = [[0,0], [0, 10], [10, 10], [10, 0], [0, 0]]
p1 = Polygon(c1)
c2 = [[10, 2], [20, 8], [20, 2], [10, 2]]
p2 = Polygon(c2)
gdf = geopandas.GeoDataFrame(geometry=[p1, p2])
base = gdf.plot(edgecolor='k', facecolor="none",alpha=0.5)
c1 = numpy.array(c1)
c2 = numpy.array(c2)
_ = base.scatter(c1[:,0], c1[:,1])
_ =base.scatter(c2[:,0], c2[:,1])
The two polygons are visually contiguous share no vertices. This will result in the two polygons not being Queen neighbors, since a necessary (and sufficient) condition for the latter is at least one shared vertex.
w = libpysal.weights.Queen.from_dataframe(gdf)
/home/serge/anaconda3/envs/dev39/lib/python3.10/site-packages/libpysal/weights/weights.py:172: UserWarning: The weights matrix is not fully connected:
There are 2 disconnected components.
There are 2 islands with ids: 0, 1.
warnings.warn(message)
Detecting nonplanar touches#
geoplanar can detect and report nonplanar edges:
geoplanar.non_planar_edges(gdf)
defaultdict(set, {0: {1}})
Fixing nonplanar edges#
gdf1 = geoplanar.fix_npe_edges(gdf)
/home/serge/anaconda3/envs/dev39/lib/python3.10/site-packages/libpysal/weights/weights.py:172: UserWarning: The weights matrix is not fully connected:
There are 2 disconnected components.
There are 2 islands with ids: 0, 1.
warnings.warn(message)
geoplanar.non_planar_edges(gdf1)
defaultdict(set, {})
w1 = libpysal.weights.Queen.from_dataframe(gdf1)
w1.neighbors
{0: [1], 1: [0]}
Default is to work on a copy#
geoplanar.non_planar_edges(gdf)
/home/serge/anaconda3/envs/dev39/lib/python3.10/site-packages/libpysal/weights/weights.py:172: UserWarning: The weights matrix is not fully connected:
There are 2 disconnected components.
There are 2 islands with ids: 0, 1.
warnings.warn(message)
defaultdict(set, {0: {1}})
geoplanar.fix_npe_edges(gdf, inplace=True)
| geometry | |
|---|---|
| 0 | POLYGON ((0.00000 0.00000, 0.00000 10.00000, 1... |
| 1 | POLYGON ((10.00000 2.00000, 20.00000 8.00000, ... |
geoplanar.non_planar_edges(gdf)
defaultdict(set, {})
w = libpysal.weights.Queen.from_dataframe(gdf)
w.neighbors
{0: [1], 1: [0]}
Handle MultiPolygons#
from shapely.geometry import MultiPolygon
c1 = [[0,0], [0, 10], [10, 10], [10, 0], [0, 0]]
p1 = Polygon(c1)
c2 = [[10, 2], [20, 8], [20, 2], [10, 2]]
p3 = Polygon([ [21, 2], [21, 4], [23,3] ])
#p2 = Polygon(c2)
p2 = MultiPolygon([Polygon(c2), p3])
gdf = geopandas.GeoDataFrame(geometry=[p1, p2])
base = gdf.plot(edgecolor='k', facecolor="none",alpha=0.5)
c1 = numpy.array(c1)
c2 = numpy.array(c2)
_ = base.scatter(c1[:,0], c1[:,1])
_ =base.scatter(c2[:,0], c2[:,1])
res = geoplanar.non_planar_edges(gdf)
/home/serge/anaconda3/envs/dev39/lib/python3.10/site-packages/libpysal/weights/weights.py:172: UserWarning: The weights matrix is not fully connected:
There are 2 disconnected components.
There are 2 islands with ids: 0, 1.
warnings.warn(message)
res
defaultdict(set, {0: {1}})
gdf1 = geoplanar.fix_npe_edges(gdf)
/home/serge/anaconda3/envs/edu_concordance/lib/python3.9/site-packages/libpysal/weights/weights.py:172: UserWarning: The weights matrix is not fully connected:
There are 2 disconnected components.
There are 2 islands with ids: 0, 1.
warnings.warn(message)
gdf1.geometry[0].wkt
'POLYGON ((0 0, 0 10, 10 10, 10 2, 10 0, 0 0))'
gdf.geometry[0].wkt
'POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))'