kikee1222
kikee1222

Reputation: 2006

plotting polygons in python using geopandas and folium

I have to plot polygons based on site 'regions'. I want a line that goes around the outside of a region to define it's perimeter.

Here is my code:

#Import the source data and libraries
import pandas as pd
import geopandas as gpd
import folium
from shapely.geometry import Polygon
df = pd.read_csv('tacs.csv')

#Extract the lat long lists from the datasource
lat_point_list = df['magnet.latitude'].tolist()
lon_point_list = df['magnet.longitude'].tolist()

#Some wizardry
polygon_geom = Polygon(zip(lon_point_list, lat_point_list))
crs = {'init': 'epsg:4326'}
polygon = gpd.GeoDataFrame(index=[0], crs=crs, geometry=[polygon_geom])       

#output to files
polygon.to_file(filename='polygon.geojson', driver='GeoJSON')
polygon.to_file(filename='polygon.shp', driver="ESRI Shapefile")

#plot on a map with central point being birmingham
m = folium.Map([51.509865, -0.118092], zoom_start=12, tiles='cartodbpositron')
folium.GeoJson(polygon).add_to(m)
folium.LatLngPopup().add_to(m)
m

The issue is, it comes out like the below. It's not a line around the perimeter, rather a big mess of interconnecting points.

Any ideas how I can get around this?

enter image description here

Upvotes: 4

Views: 11689

Answers (2)

ptrpang
ptrpang

Reputation: 21

A convex hull of a non-convex polygon is not the perimeter. One way of doing this (there is probably a better way) is to recast the polygon as a LinearRing:

#a polygon:
R = shapely.geometry.Polygon([[1,2],[2,3],[3,2],[1,2]])
#cast as linearring:
L = shapely.geometry.LinearRing(R.exterior.coords)

Then you can replace the geometry column of Polygons in you geodataframe with a geometry column of LinearRings/LineStrings, and plot those instead.

Upvotes: 2

Ricardo Rendich
Ricardo Rendich

Reputation: 651

There is an atribute called convex_hull. According to this documentation:

GeoSeries.convex_hull Returns a GeoSeries of geometries representing the convex hull of each geometry.

The convex hull of a geometry is the smallest convex Polygon containing all the points in each geometry, unless the number of points in the geometric object is less than three. For two points, the convex hull collapses to a LineString; for 1, a Point.

Here is an example:

import geopandas as gpd
from shapely.geometry import Polygon

lat_point_list = [50.854457, 48.853033, 52.518172, 50.072651, 50.854457]
lon_point_list = [4.377184, 2.349553, 13.407759, 14.435935, 4.377184]

polygon_geom = Polygon(zip(lon_point_list, lat_point_list))
polygon_geom2 = polygon_geom.convex_hull # the atribute
import folium
m = folium.Map([50.854457, 4.377184], zoom_start=5, tiles='cartodbpositron')
folium.GeoJson(polygon_geom).add_to(m)
folium.GeoJson(polygon_geom2).add_to(m)
folium.LatLngPopup().add_to(m)
m

Upvotes: 3

Related Questions