core
core copied to clipboard
Only finding 390 roads in all of Norway
Using geofabrik.de's dataset for Norway (http://download.geofabrik.de/europe/norway-latest.osm.pbf).
public void GetAllRoads()
{
var directory = $"{Directory.GetCurrentDirectory()}{@"\wwwroot\files\norway-latest.osm.pbf"}";
using (var fileStream = new FileInfo(directory).OpenRead())
{
var source = new PBFOsmStreamSource(fileStream);
var filtered = source.Where(x => x.Type == OsmSharp.OsmGeoType.Way || x.Tags.ContainsKey("highway"));
var features = filtered.ToFeatureSource();
var items = features.ToList();
var ItemCount = items.Count(); //168571
var lineStrings = items.Where(x => x.Geometry.GeometryType == "LineString").ToList();
var lineStringCount = lineStrings.Count(); //390
}
}
I don't understand why I can only find 390 roads in Norway, what am I doing wrong?
Actually, I can't find a single item marked with OsmSharp.Type.Way
public void GetAllRoads()
{
var directory = $"{Directory.GetCurrentDirectory()}{@"\wwwroot\files\norway-latest.osm.pbf"}";
using (var fileStream = new FileInfo(directory).OpenRead())
{
var source = new PBFOsmStreamSource(fileStream);
var filtered = source.Where(x => x.Type == OsmSharp.OsmGeoType.Way);
var completes = filtered.ToFeatureSource();
var completesCount = completes.Count(); //0
}
}
I see that the source filter works as it should, it provides all roads in Norway; each item with a node list of type long (Which I assume are Node ID's?).
Is it ToFeatureSource that is not able to convert the nodes to a LineString for some reason?
What if you leave out the call to tofeaturesource?
What if you leave out the call to tofeaturesource?
That gives me a list of what I assume are node id's of type long, I thought ToFeatureSource was supposed to then find the nodes and make a LineString of them, with actual coordinates? This is probably what I'm doing wrong then.
Or am I meant to manually look up each node ID and extract the coordinates myself?

I'm using the net6.0 Framework, might that be an issue?
You should not filter out the Nodes here:
var filtered = source.Where(x => x.Type == OsmSharp.OsmGeoType.Way);
Perhaps this will work:
var filtered = source.Where(x => x.Type == OsmSharp.OsmGeoType.Way || x.Type == OsmSharp.OsmGeoType.Node );
The feature source needs the nodes to build the linestrings for the ways. Without the nodes it can't do anything.
You probably get 390 because by coincidence some nodes have a highway tag. The 168571 are all the nodes with a highway tag most likely plus the 390.
The feature source needs the nodes to build the linestrings for the ways. Without the nodes it can't do anything.
Ah, that makes total sense. Even obvious, now that you point it out.
The only problem I have with that is that it requires a huge amount of memory, is there a built in way for it to traverse the data without having to commit all the node data to memory? Basically exchanging speed for less memory usage?
You can first filter out only the ways you need, look at their nodes and keep a set of node ids you need. Then do a second pass and only keep the nodes you need.