In [1]:
# Allow to import without installing
import sys
sys.path.insert(0, "..")
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import geopandas as gpd
We firstly explore how to do this by using the GeoJSON schema.
__geo_interface__".It's then as simple as this...
In [2]:
point_features = [{"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0", "prop1": "value1"
}
}]
point_data = gpd.GeoDataFrame.from_features(point_features)
point_data
Out[2]:
In [3]:
point_data.ix[0].geometry
Out[3]:
In [4]:
line_features = [{"geometry": {
"type": "LineString",
"coordinates": [[102.0, 0.5], [104, 3], [103, 2]]
},
"properties": {
"prop3": "value3"
}
}]
line_data = gpd.GeoDataFrame.from_features(line_features)
line_data
Out[4]:
In [5]:
line_data.ix[0].geometry
Out[5]:
In [6]:
polygon_features = [{"geometry": {
"type": "Polygon",
"coordinates": [[[102.0, 0.5], [104, 3], [102, 2], [102,0.5]]]
},
"properties": {
"prop4": "value4", "prop1": "value1"
}
}]
data = gpd.GeoDataFrame.from_features(polygon_features)
data
Out[6]:
In [7]:
data.plot()
Out[7]:
In [8]:
data.ix[0].geometry
Out[8]:
In [9]:
features = []
features.extend(point_features)
features.extend(line_features)
features.extend(polygon_features)
gpd.GeoDataFrame.from_features(features)
Out[9]:
Some things that jumped out at me as I read the GeoJSON spec:
In [10]:
type(point_data.geometry[0]), type(line_data.geometry[0]), type(data.geometry[0])
Out[10]:
In [11]:
import shapely.geometry
In [12]:
pts = shapely.geometry.LineString([shapely.geometry.Point(0,0), shapely.geometry.Point(1,0), shapely.geometry.Point(1,1)])
df = gpd.GeoDataFrame({"geometry": [pts], "key1":["value1"], "key2":["value2"]})
df
Out[12]:
In [13]:
df.ix[0].geometry
Out[13]:
In [14]:
import osmdigest.geometry as geometry
import osmdigest.sqlite as sq
import os
filename = os.path.join("..", "..", "..", "Data", "california-latest.db")
In [15]:
db = sq.OSM_SQLite(filename)
way = db.complete_way(33088737)
series = geometry.geoseries_from_way(way)
series
Out[15]:
In [16]:
gpd.GeoDataFrame(series).T.plot()
Out[16]:
In [17]:
way = db.complete_way(285549437)
series = geometry.geoseries_from_way(way)
series
Out[17]:
In [18]:
df = gpd.GeoDataFrame(series).T
df
Out[18]:
In [19]:
df.plot()
Out[19]:
In [20]:
relation = db.complete_relation(2866485)
geometry.geodataframe_from_relation(relation)
Out[20]:
In [21]:
geometry.geodataframe_from_relation( db.complete_relation(63222) )
Out[21]:
These are harder to compute automatically, because the exact interpretation of the sub-elements depends upon context. However, most relations which have "interesting" geometry (as opposed to giving contextual information on other elements) are of "multi-polygon" type, and can be recognised by the presence of ways with the "role" of "inner" or "outer".
I found that using the shapely library itself was the easiest way to conver the geometry.
There are some cases of geometry which shapely cannot handle. For example:
In [264]:
gen = db.relations()
for _ in range(15):
next(gen)
relation = next(gen)
print(relation)
series = geometry.geoseries_from_relation(db.complete_relation(relation))
series
Out[264]:
In [265]:
gpd.GeoDataFrame(series).T.plot()
Out[265]: