Main Content

Read Data from OpenStreetMap Files

Since R2023b

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, and address.

  • 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,:);

Display the subway entrances on the same map.

hold on
geoplot(entrance,"*")
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

Objects

Related Topics