Using profile XML snippets

While xServer internet uses HTTP basic authentication with <user>/<password>, it is highly recommended to work with the token assigned to your subscription using the combination “xtok”/<token>. Using the token is a safer way than using your far more sensible account data.

This tutorial shows a convenient and type-safe way to use the xServer profile XML snippets in C#. Profile snippets can be used to pass additional engine parameters, which are not part of the SOAP API. The sample uses xServer access via WCF (see Access via WCF). But the same can also be applied to WebReference classes and the client access classes which come with PTV xServer.

Step 1: Get the XRouteProfile.xsd and GeoDatasource.xsd schema files

Step 2: Use xsd.exe tool to generate C# classes from the schema

Use the xsd tool (usually located in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin) to generate the classes holding the profile properties:

     xsd.exe /c XRouteProfile.xsd GeoDatasource.xsd

Then add the generated file (XRouteProfile_GeoDatasource.cs) to your project.

Step 3: Add a helper method to serialize the profile class

We are going to need the following using directives for our sample:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

using ProfileXmlDemo.XRouteServiceReference;

xServer needs UTF-8 encoding for the profile, but when using the standard StringWriter, an UTF-16 string is created. The helper class explained at the link http://devproj20.blogspot.de/2008/02/writing-xml-with-utf-8-encoding-using.html shows how to enforce UTF-8. For convenient conversion we also add an extension method to the profile class, so we can build the snippet string using Profile.ToSnippet(). Furthermore we set the credentials for our client class (Learn more).

// helper method to serialize a profile to a snippet string
    public static class XRouteHelper
    {
        public static string ToSnippet(this Profile profile)
        {
            var ser = new XmlSerializer(typeof(Profile));
            var sb = new StringBuilder();
            var writer = new XmlTextWriter(new StringWriterWithEncoding(sb, Encoding.UTF8));
            ser.Serialize(writer, profile);
            return sb.ToString();
        }
    }

    // http://devproj20.blogspot.de/2008/02/writing-xml-with-utf-8-encoding-using.html
    public class StringWriterWithEncoding : StringWriter
    {
        Encoding encoding;

        public StringWriterWithEncoding(StringBuilder builder, Encoding encoding)
            : base(builder)
        {
            this.encoding = encoding;
        }

        public override Encoding Encoding
        {
            get { return encoding; }
        }
    }

	public class XRouteWSClientWithCredentials : XRouteWSClient
	{
	    public XRouteWSClientWithCredentials()
	    {
	        ClientCredentials.UserName.UserName = "xtok";
            ClientCredentials.UserName.Password = "<enter your token here>";
	    }
	}

Finally: Easily add the snippet to your request

Just build up the profile and add profile.ToSnippet() to the caller context.

internal class Program
    {
        private static void Main(string[] args)
        {
            var xRouteClient = new XRouteWSClientWithCredentials();

            // build the profile programmatically
            var profile = new Profile
            {
                Routing = new Routing
                {
                    majorVersion = "2",
                    minorVersion = "0",
                    Vehicle = new RoutingVehicle
                    {
                        Physical = new RoutingVehiclePhysical
                        {
                            Dimension = new RoutingVehiclePhysicalDimension { height = 500 }
                        }
                    },
                    Course = new RoutingCourse
                    {
                        AdditionalDataRules = new RoutingCourseAdditionalDataRules
                        {
                            enabled = true,
                            layerName = "TruckAttributes",
                            VehicleSpecific = new RoutingCourseAdditionalDataRulesVehicleSpecific { enabled = true }
                        }
                    }
                }
            };

            // invoke the request with the profile
            var xRouteResult = xRouteClient.calculateRoute(new[] {
                    new WaypointDesc {wrappedCoords = new[] {new Point {point = new PlainPoint {x = 7.10, y = 50.73}}}},
                    new WaypointDesc {wrappedCoords = new[] {new Point {point = new PlainPoint {x = 10.00, y = 53.55}}}}},
                null, null, new ResultListOptions(), // just need the distance
                new CallerContext { wrappedProperties = new[] {
                    new CallerContextProperty {key = "CoordFormat", value = "OG_GEODECIMAL"},
                    new CallerContextProperty {key = "ProfileXMLSnippet", value = profile.ToSnippet()}}});

            System.Console.WriteLine("Distance: " + xRouteResult.info.distance);
            System.Console.ReadLine();
        }
    }

The ouput of this sample should now look like this: