Read Data from OpenStreetMap Files
This example shows how to read OpenStreetMap® files into geospatial tables and then find locations stored in the table based on their tags.
OpenStreetMap files provide information about locations using tags. Each tag consists of a key and a value.
The key provides context for the location. OpenStreetMap supports thousands of keys, such as
highway
,building
, andaddress
.The value provides detail about the key. Each key can support hundreds of values. For example, values for the
highway
key include"yes"
,"primary"
,"footway"
, and"cycleway"
.
A geospatial table is a table
or timetable
object that contains a Shape
table variable and attribute table variables. When you read data from an OpenStreetMap file into a geospatial table by using the readgeotable
function, the geospatial table stores the tags using the attribute table variables. For common tags, the names of the variables match the keys. For uncommon tags, the table stores the keys and values in the other_tags_dictionary
variable. Most locations stored in OpenStreetMap files do not have values for all tags.
Read Data from File
Specify the name of an OpenStreetMap file [1] containing data for several city blocks in Shibuya, Tokyo, Japan.
filename = "shibuya.osm";
Read the lines and points layers from the file into geospatial tables.
The lines layer represents features such as roads, sidewalks, and railroad tracks. The table represents the lines using line shapes in geographic coordinates.
The points layer represents features such as traffic signals, bus stops, and subway entrances. The table represents the points using point shapes in geographic coordinates.
linesLayer = readgeotable(filename,Layer="lines"); pointsLayer = readgeotable(filename,Layer="points");
Find Locations with Tag
Display lines and points with a railway
tag from an OpenStreetMap file. OpenStreetMap files use the railway
tag to specify information about railways. For example, a railway
tag can identify a line as a subway route and a point as a station entrance.
Query Tags Stored in Table Variables
The lines layer includes the railway
key as a table variable. You can verify that the table has a railway
variable by using the matches
function.
matches("railway",linesLayer.Properties.VariableNames)
ans = logical
1
Find the table rows that have railway
tags. If a table row does not have a railway
tag, then the value of the railway
key for that row is ""
. Create a new geospatial table from the table rows with railway
tags.
idxRailways = ~ismissing(linesLayer.railway,"");
railways = linesLayer(idxRailways,:);
Display the line shapes with railway
tags on a map.
figure
geoplot(railways)
title("Railway Lines")
Query Tags Stored in other_tags_dictionary
The railway
tag is less common for the points layer, so the points layer stores instances of the railway
tag in the other_tags_dictionary
variable. You can verify that the table does not have a railway
variable by using the matches
function.
matches("railway",pointsLayer.Properties.VariableNames)
ans = logical
0
The other_tags_dictionary
variable stores tags in cell arrays of dictionaries. Find the table rows that contain railway
tags by using a loop. For each row of the table, get the dictionary from the cell array stored in the other_tags_dictionary
variable. Then, determine whether the dictionary contains a railway
tag.
numRows = height(pointsLayer); hasRailwayTag = false(numRows,1); for row = 1:numRows dict = pointsLayer.other_tags_dictionary{row}; hasRailwayTag(row) = isKey(dict,"railway"); end
Verify that at least one of the table rows contains a railway
tag.
any(hasRailwayTag)
ans = logical
1
Create a new geospatial table from the table rows with railway
tags.
railpoints = pointsLayer(hasRailwayTag,:);
Display the points with railway
tags on the same map as the lines.
hold on geoplot(railpoints,"*") title("Railway Lines and Points")
Find Tags with Specified Values
Display lines that represent footpaths and points that represent subway entrances. OpenStreetMap files identify footpaths using the highway
key and the "footway"
value, and they identify subway entrances using the railway
key and the "subway_entrance"
value.
Query Tags and Values Stored in Table Variables
The lines layer includes the highway
key as a table variable. You can verify that the table has a highway
variable by using the matches
function.
matches("highway",linesLayer.Properties.VariableNames)
ans = logical
1
Find the table rows that represent footpaths. Create a new geospatial table from the footpath table rows.
isFootpath = linesLayer.highway == "footway";
footway = linesLayer(isFootpath,:);
Display the footpaths on a map. Zoom in to the footpaths surrounding Shibuya Station.
figure
geoplot(footway)
geolimits([35.6583 35.6602],[139.6983 139.7012])
title("Footpaths")
Query Tags and Values Stored in other_tags_dictionary
Extract instances of the railway
tag from the other_tags_dictionary
variable and store the values using a new table variable.
The points layer stores instances of the railway
tag in the other_tags_dictionary
variable. You can verify that the table does not have a railway
variable by using the matches
function.
matches("railway",pointsLayer.Properties.VariableNames)
ans = logical
0
The other_tags_dictionary
variable stores tags in cell arrays of dictionaries. Create a new table variable called railway
that contains ""
values. Then, add data to the variable by using a loop. For each row of the table, get the dictionary from the cell array stored in the other_tags_dictionary
variable. If the dictionary contains the railway
tag, add the value to the railway
variable.
numRows = height(pointsLayer); pointsLayer.railway = strings(numRows,1); for row = 1:numRows dict = pointsLayer.other_tags_dictionary{row}; hasTag = isKey(dict,"railway"); if hasTag pointsLayer.railway(row) = dict("railway"); end end
Find the table rows that represent subway entrances by querying the railway
variable. Create a new geospatial table from the table rows.
idxEntrance = pointsLayer.railway == "subway_entrance";
entrance = pointsLayer(idxEntrance,:);
Extract the latitude and longitude coordinates from the table. Then, on the same map, display the subway entrances using pushpin icons.
lat = entrance.Shape.Latitude; lon = entrance.Shape.Longitude; hold on geoiconchart(lat,lon,SizeData=30) title("Footpaths and Subway Entrances")
[1] You can download OpenStreetMap files from https://www.openstreetmap.org, which provides access to crowd-sourced map data all over the world. The data is licensed under the Open Data Commons Open Database License (ODbL), https://opendatacommons.org/licenses/odbl/.
See Also
Functions
readgeotable
|matches
|ismissing
|isKey