Search code examples
c#openstreetmap

How to run an application and send file names?


I've donwloaded the following maps:

andorra-latest.osm.pbf       https://download.geofabrik.de/europe/andorra-latest.osm.pbf
azores-latest.osm.pbf        https://download.geofabrik.de/europe/azores-latest.osm.pbf
cyprus-latest.osm.pbf        https://download.geofabrik.de/europe/cyprus-latest.osm.pbf

I need to merge the above maps. So I am using osmconvert to merge maps. I read this answer about merging maps. So if I copy the following command and paste into command window, then it works fine - it creates all.osm.pbf file:

enter image description here

So desired file all.osm.pbf is created:

enter image description here

However, now I would like to call this command programmatically. I mean, I would like to call the above command through C#. So I've tried this code in my Console application:

static Process process = new Process();

static void Main(string[] args)
{
    process.EnableRaisingEvents = true;
    process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
    process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
    process.Exited += new System.EventHandler(process_Exited);

    process.StartInfo.FileName = @"osmconvert.exe";
    process.StartInfo.Arguments = @"osmconvert.exe andorra-latest.osm.pbf --out-o5m | osmconvert.exe - azores-latest.osm.pbf | osmconvert.exe - cyprus-latest.osm.pbf -o=all.osm.pbf";
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardOutput = true;

    process.Start();
    process.BeginErrorReadLine();
    process.BeginOutputReadLine();
}

But I always see the following error:

enter image description here]

My files are located in D:\Downloads:

enter image description here

Could you say, please, what am I doing wrong?

UPDATE:

I've tried this code, however, the error is the same:

process.StartInfo.FileName = @"D:\Downloads\osmconvert.exe";
process.StartInfo.Arguments = @"D:\Downloads\osmconvert.exe D:\Downloads\andorra-latest.osm.pbf --out-o5m | D:\Downloads\osmconvert.exe - D:\Downloads\azores-latest.osm.pbf | D:\Downloads\osmconvert.exe - D:\Downloads\cyprus-latest.osm.pbf -o=D:\Downloads\all.osm.pbf";

and this approach:

process.StartInfo.FileName = @"D:\\Downloads\\osmconvert.exe";
process.StartInfo.Arguments = @"D:\\Downloads\\osmconvert.exe D:\\Downloads\\andorra-latest.osm.pbf --out-o5m | D:\\Downloads\\osmconvert.exe - D:\\Downloads\\azores-latest.osm.pbf | D:\\Downloads\\osmconvert.exe - D:\\Downloads\\cyprus-latest.osm.pbf -o=D:\\Downloads\\all.osm.pbf";

Solution

  • I think the problem is that you are sending osmconvert.exe as the first command line argument. The executable is probably trying to open itself and process it as map data. That likely fails because it is trying to be opened in a way (read/write) that isn't possible when it is also executing.

    Instead, you could "programatically" invoke cmd.exe and tell it to execute the commands:

    static Process process = new Process();
    
    static void Main(string[] args)
    {
        process.Exited += new System.EventHandler(process_Exited);
    
        // create a cmd.exe process.
        process.StartInfo.FileName = @"cmd.exe";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardInput = true;
        process.Start();
    
        var input = process.StandardInput;
        // tell cmd.exe to do your bidding.
        input.WriteLine("osmconvert.exe andorra-latest.osm.pbf --out-o5m | osmconvert.exe - azores-latest.osm.pbf | osmconvert.exe - cyprus-latest.osm.pbf -o=all.osm.pbf");
        // then tell it to exit.
        input.WriteLine("exit");
        // process.Exited event should fire at this point.
        // or you could process.WaitForExit() instead.
    }