Cannot implicitly convert type 'Plantool.xRoute.LineString[]' to 'Plantool.xMap.LineString[]'

StackOverflow https://stackoverflow.com/questions/13976559

  •  11-12-2021
  •  | 
  •  

Question

Situation: I have 3 web references (xMap, xLocation, xRoute) xMap is dedicated to generating maps. xLocation is dedicated to locating places. xRoute is dedicated to generating routes.

I am using a simple GUI to display the map and inputting locations for the start and destination routes.

These are my errors.

Error 1 Cannot implicitly convert type 'Plantool.xRoute.LineString[]' to 'Plantool.xMap.LineString[]'

Error 2 The best overloaded method match for 'Plantool.xMap.XMapWSService.renderMapBoundingBox(Plantool.xMap.BoundingBox, Plantool.xMap.MapParams, Plantool.xMap.ImageInfo, Plantool.xMap.Layer[], bool, Plantool.xMap.CallerContext)' has some invalid arguments

Error 3 Argument '1': cannot convert from 'Plantool.xRoute.BoundingBox' to 'Plantool.xMap.BoundingBox'

I am guessing that PTV xServer's duplicate methods/features/etc are the same as xMap, xLocate, xRoute are optional modules. It is probably a simple answer is there a solution to this?

I am looking a head for a long trip home and spend an additional addicted half an hour of overtime on this code. And hi, I'm new.

Below his my class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Plantool.xMap;
using Plantool.xLocate;
using Plantool.xRoute;

namespace Plantool
{
    class ClassMap
    {
        /*
         * xServer clients
         */
        private static XMapWSService xMapClient = new XMapWSService();
        private static XRouteWSService xRouteClient = new XRouteWSService();
        private static XLocateWSService xLocateClient = new XLocateWSService();

        /* getLocation()
         * Input: Address string
         * Output: WKT (Well-Known-Text) Location
         * Edited 20/12/12 - Davide Nguyen
         */
        public string getLocation(string input)
        {
            // create the adress object
            string[] address = input.Split(',');
            Address addr = new Address();
            addr.country = address[0];
            addr.city = address[1];
            addr.postCode = address[2];

            // call findAddress on the xLocate server  
            // only the first argument of findAddress is mandatory,  
            // all others are nullable (see xLocate API documentation)
            AddressResponse response = xLocateClient.findAddress(addr, null, null, null, null);

            string result = "";
            foreach (ResultAddress ra in response.wrappedResultList)
            {
                result += String.Format("POINT( {0} {1}) ", ra.coordinates.point.x, ra.coordinates.point.y);
            }
            string result2 = result.Replace(",", ".");
            return result2;
        }

        /* route()
         * Input: Start address, Destination address
         * Output: string[] [0] DISTANCE [1] TIME [2] MAP
         * Edited 20/12/12 - Davide Nguyen
         */
        public string[] route(string startlocation, string destination)
        {
            #region WaypointDesc[]
            // create the WayPoint for the Start
            // ATTENTION: Here at the object WaypointDesc the parameters are not named
            // "coords" as described within the documentation but
            // "wrappedCoords"
            WaypointDesc wpdStart = new WaypointDesc();
            // please note that this has to be an array of Point...
            wpdStart.wrappedCoords = new xRoute.Point[] { new xRoute.Point() };
            wpdStart.wrappedCoords[0].wkt = getLocation(startlocation);

            // Waypoint for the Destination...
            WaypointDesc wpdDestination = new WaypointDesc();
            wpdDestination.wrappedCoords = new xRoute.Point[] { new xRoute.Point() };
            wpdDestination.wrappedCoords[0].wkt = getLocation(destination);

            // create a new array of WayPointDescriptions and fill it with Start and Destination
            WaypointDesc[] waypointDesc = new WaypointDesc[] { wpdStart, wpdDestination };
            #endregion

            try
            {
                // Route
                Route route = calculateRoute(waypointDesc);

                // Map
                string DisplayMapURL = createMap(waypointDesc, route);

                // get route info
                string[] routeinfo = getRouteInfo(waypointDesc);

                // Create the result
                string[] result = new string[3];
                result[0] = routeinfo[0]; // Distance
                result[1] = routeinfo[1]; // Time
                result[2] = DisplayMapURL;// Map URL

                // Return the result
                return result;
            }
            catch
            {
                throw new NotImplementedException();
            }
        }

        /* getRouteInfo()
         * Input: WaypointDesc[]
         * Output: string mapURL
         * Edited 20/12/12 - Davide Nguyen
         */
        private static string createMap(WaypointDesc[] waypointDesc, Route route)
        {
            #region boundingBox
            // Set boundingBox fand use corners from the calculated route
            xRoute.BoundingBox boundingBox = new xRoute.BoundingBox();
            boundingBox.leftTop = route.totalRectangle.rightTop;
            boundingBox.rightBottom = route.totalRectangle.leftBottom;
            #endregion

            #region mapParams
            // Build mapParams
            MapParams mapParams = new MapParams();
            mapParams.showScale = true;
            mapParams.useMiles = false;
            #endregion

            #region imageInfo
            // Create imageInfo and set the frame size and image format. NOTE: 1052; 863
            ImageInfo imageInfo = new ImageInfo();
            imageInfo.format = ImageFileFormat.PNG;
            imageInfo.height = 1052;
            imageInfo.width = 863;
            imageInfo.imageParameter = "";
            #endregion

            #region layers
            // Create a line from the calculated route
            xRoute.LineString[] lineStrings = new xRoute.LineString[] { route.polygon };
            Lines[] lines = new Lines[1];
            LineOptions options = new LineOptions();
            LinePartOptions partoptions = new LinePartOptions();
            partoptions.color = new Color();
            partoptions.visible = true;
            partoptions.width = -10;
            options.mainLine = partoptions;

            lines[0] = new Lines();
            lines[0].wrappedLines = lineStrings;                                                                                    //NEED HELP
            lines[0].options = options;

            // Define customLayer that contains the object lines and set layers.
            CustomLayer customLayer = new CustomLayer();
            customLayer.visible = true;
            customLayer.drawPriority = 100;
            customLayer.wrappedLines = lines;
            customLayer.objectInfos = ObjectInfoType.NONE;
            customLayer.centerObjects = true;
            Layer[] layers = new Layer[] { customLayer };
            #endregion

            #region includeImageInResponse
            // Set argument includeImageInResponse to false (default).
            Boolean includeImageInResponse = false;
            #endregion

            // Return object map using the following method.
            Map map = xMapClient.renderMapBoundingBox(boundingBox, mapParams, imageInfo, layers, includeImageInResponse, null);     // NEED HELP

            // Retrieve the image
            string result = "http://" + map.image.url;

            // Return the drawn map
            return result;
        }

        /* getRouteInfo()
         * Input: WaypointDesc[]
         * Output: string[] [0] Distance in M [1] Time in H:M:S:MS
         * Edited 20/12/12 - Davide Nguyen
         */
        private string[] getRouteInfo(WaypointDesc[] waypointDesc)
        {
            // Call the service
            RouteInfo routeInfo = xRouteClient.calculateRouteInfo(waypointDesc, null, null, null);

            // Create the result
            TimeSpan t = TimeSpan.FromSeconds(routeInfo.time);
            string[] result = new string[2];
            result[0] = string.Format("{0} KM", routeInfo.distance);
            result[1] = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms", t.Hours, t.Minutes, t.Seconds, t.Milliseconds);

            // Return the result
            return result;
        }

        /* getRouteLines() 
         * Input: WaypointDesc[]
         * Output: Route object
         * Edited 20/12/12 - Davide Nguyen
         */
        private static Route calculateRoute(WaypointDesc[] waypointDesc)
        {
            #region ResultListOptions
            // Instantiate a new object resultListOPtions
            ResultListOptions resultListOptions = new ResultListOptions();
            resultListOptions.polygon = true;
            resultListOptions.totalRectangle = true;
            resultListOptions.detailLevel = DetailLevel.STANDARD;
            #endregion

            #region CallerContext/CallerContextPropery
            // Create a new CallerContextProperty object property
            xRoute.CallerContextProperty property = new xRoute.CallerContextProperty();
            property.key = "ResponseGeometry";
            property.value = "WKT";
            xRoute.CallerContext callerContext = new xRoute.CallerContext();
            callerContext.wrappedProperties = new xRoute.CallerContextProperty[] { property };
            #endregion

            // Call the service
            Route route = xRouteClient.calculateRoute(waypointDesc, null, null, resultListOptions, callerContext);

            return route;
        }

    }
}
Was it helpful?

Solution

There seems to be some reference confusion between these two.

using Plantool.xMap;
using Plantool.xRoute;

You could delete these:

using Plantool.xMap;
using Plantool.xLocate;
using Plantool.xRoute;

And just add this:

using Plantool;

And then explicitly reference the correct types, ensuring you are referencing the one that is required. This should solve all three error messages.

Ideally, you should avoid having name-clashes where only the namespace is different. In the .NET framework you'll notice that they take care to avoid this, for example...

System.Data.Odbc.OdbcConnection
 System.Data.SqlClient.SqlConnection

They could have both been called Connection, given that one is in the Odbc namespace and one is in the SqlClient namespace - but this could lead to the problem you have.

By renaming LineString to RouteLineString and MapLineString you can avoid the confusion in your application.

OTHER TIPS

From what I remember from xServer, this was a major issue: common types from xMap, xRoute and xLocate are not the same (just like you said, because those are optional modules). xMap.LineString is actually a different type from xRoute.LineString, even if they have identical properties. There's nothing you can do about it, except:

  • if both types share a common base type or interface, use this common type instead
  • write extension methods to map from xRoute.LineString to xLocate.LineString...etc.

For instance:

public static xLocate.LineString ToXLocateLineString(this xRoute.LineString lineString)
{
    return new xLocate.LineString
    {
        // Map type by copying properties
        ....
    };
}

So you can write

xRoute.LineString[] input = ....
xMap.LineString[] output = input.Select(z => z.ToXLocateLineString()).ToArray();

Or even

public static xLocate.LineString[] ToXLocateLineStringArray(this xRoute.LineString[] lineString)
{
    return lineString.Select(z => z.ToXLocateLineString()).ToArray();
}

then

xMap.LineString[] output = input.ToXLocateLineStringArray();

Maybe they improved their API since I used it for the last time, not sure about that.

Cheers, in my eyes the redundance can be resolved by a proper creation of client classes. Instead of adding three WSDL's one by one (through the Visual Studio Wizzards) you could merge the WSDLs in a single step by using the WSDL.EXE of Visual Studio. This worked with PTV xServer 1 (which was referenced in this thread) and even better with xServer2 What I usually do is a CMD statement such as

WSDL /namespace:"XServer" /sharetypes /out:"XServer.cs" "https://xserver2-europe-eu-test.cloud.ptvgroup.com/services/ws/XLocate?wsdl" "https://xserver2-europe-eu-test.cloud.ptvgroup.com/services/ws/XRoute?wsdl" "https://xserver2-europe-eu-test.cloud.ptvgroup.com/services/ws/XTour?wsdl"

See this as a generic advice. Mapping interfaces are completely different nowadays.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top