Firstly what you probably want to do is use Assets and follow this Tutorial
Including files as your application doesnt work the same as if you were to access them directly on the file system. Now you wont be able to get FileInfo
from the asset but you will be able to read them.
First place the ireland.osm.pbf
file in the Assets
directory. Next you must (and usually does it for you if you choose Add Existing Item) set the Build Action to AndroidAsset
. This builds (packages) the file as part of the Android Package.
Next Assets are loaded (accessed) through the AssetManager
. Luckily this is available in the Activity Context through this.Assets
.
To read the asset is quite simple.
using (StreamReader sr = new StreamReader (Assets.Open ("ireland.osm.pbf")))
{
//do as you wish with the stream reader.
}
Edit:
From the comment.
but i need the FileInfo to implement the PBFOsmStreamSource() as shown here link
I had a quick look at the source code for PBFOsmStreamSource()
and has the constructor:
/// <summary>
/// Creates a new source of PBF formated OSM data.
/// </summary>
/// <param name="stream"></param>
public PBFOsmStreamSource(Stream stream)
{
_stream = stream;
}
Now stream reader is NOT a Stream
we need to convert it to a Stream
however does have the property BaseStream
. Now given I dont have a test enviroment you should be able to call.
using (StreamReader sr = new StreamReader(Assets.Open("ireland.osm.pbf")))
{
//do as you wish with the stream reader.
var pbfStreamSource = new PBFOsmStreamSource(sr.BaseStream);
}
EDIT 2
StreamReader.BaseStream()
does not support the Seek()
method. Reading further on the source for PBFOsmStreamSource
shows.
private void Initialize()
{
_stream.Seek(0, SeekOrigin.Begin);
this.InitializePBFReader();
}
Which is why you are getting the System.NotSupportedException
exception. Therefore you will need to construct a stream that supports the Seek()
method. Fortunatly MemoryStream
is capable of changing the position and supports the Seek()
method.
Again, I do not have a test enviroment.
using (StreamReader sr = new StreamReader(Assets.Open("ireland.osm.pbf")))
{
using (var ms = new MemoryStream())
{
sr.BaseStream.CopyTo(ms);
var pbfStreamSource = new PBFOsmStreamSource(ms);
}
}
Final Edit
After more review and looking at their samples I have written an example console application that uses StreamReader
in the same fasion as you would on the mobile. Now I have tweaked this slightly so we can dispose of the StreamReader
quickly as these files consume a large amount of memory and there is no need to keep both streams open at once.
using OsmSharp.Geo;
using OsmSharp.Osm.PBF.Streams;
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
namespace Sample.GeometryStream
{
class Program
{
static void Main(string[] args)
{
Test();
Console.ReadLine();
}
static async Task Test()
{
await ToFile("http://files.itinero.tech/data/OSM/planet/europe/luxembourg-latest.osm.pbf", "test.pbf");
var sr = new StreamReader("test.pbf");
using (var ms = new MemoryStream())
{
try
{
sr.BaseStream.CopyTo(ms);
}
catch
{
//TODO: Handle exceptions
}
finally
{
sr.Close();
sr.Dispose();
}
var pbfStreamSource = new PBFOsmStreamSource(ms);
}
}
public static async Task ToFile(string url, string filename)
{
if (!File.Exists(filename))
{
var client = new HttpClient();
using (var stream = await client.GetStreamAsync(url))
using (var outputStream = File.OpenWrite(filename))
{
stream.CopyTo(outputStream);
}
}
}
}
}