ThinkGeo.com    |     Documentation    |     Premium Support

Routing - not working with the rtg file for data in SQLlite

Hi,
I am using the WorldStreetLayer sample which has the data stored in the SQL lite file. How do we created the rtg file and the index file for testing the routing functionality.

The sample we have on routing is using the shape file.

Thanks
Naren

Hi Naren,

I found we have a sample here which can generate the rtg file, you can refer it.

https://github.com/ThinkGeo/OsmWorldMapKit-RoutingIndexGenerator

Wish that’s helpful.

Regards,

Ethan

I tried creating the rtg file using the tool and it worked.

When I tried to do the routing in the application it is saying “No Route found”

App.config


Added the following code in worldStreetsLayerSample - Form1.cs

        startFeature = new Feature(new PointShape(-96.80629120, 32.79319788));
        endFeature = new Feature(new PointShape(-96.72749863, 32.81208063));


        pointLayer.InternalFeatures.Add(startFeature);
        pointLayer.InternalFeatures.Add(endFeature);

private void AddRoutingLayer()
{
featureSource = new ShapeFileFeatureSource(Path.Combine(
ConfigurationManager.AppSettings[“RouteBasePath”],
ConfigurationManager.AppSettings[“SourceShapeFile”]));

        routingSource = new RtgRoutingSource(Path.Combine(
            ConfigurationManager.AppSettings["RouteBasePath"],
            ConfigurationManager.AppSettings["FastRouteFile"]));

        routingEngine = new RoutingEngine(routingSource, featureSource);
        routingEngine.RoutingAlgorithm.FindingRoute += new EventHandler<FindingRouteRoutingAlgorithmEventArgs>(RoutingAlgorithm_FindingRoute);

        isAddingRoadblocks = false;
        avoidableFeatureIds = new Collection<string>();

        routingLayer = new RoutingLayer();
        routingLayer.StartPoint = new PointShape(startFeature.GetWellKnownBinary());
        routingLayer.EndPoint = new PointShape(endFeature.GetWellKnownBinary());

        routingOverlay = new LayerOverlay();
        routingOverlay.Layers.Add("PHX_RoutingLayer", routingLayer);
        winformsMap1.Overlays.Add("RoutingOverlay", routingOverlay);

        roadblocksLayer = new InMemoryFeatureLayer();
        roadblocksLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = new PointStyle(new GeoImage(
            ConfigurationManager.AppSettings["RouteBasePath"] + "RoadBlock.png"));

        roadblocksLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
        routingOverlay.Layers.Add("roadblocksLayer", roadblocksLayer);

        InMemoryFeatureLayer routingExtentLayer = new InMemoryFeatureLayer();
        routingExtentLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Green));
        routingExtentLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
        routingExtentLayer.InternalFeatures.Add(new Feature(
            new RectangleShape(-96.930929, 32.878436, -96.640798, 32.710878)));

        routingOverlay.Layers.Add("RoutingExtentLayer", routingExtentLayer);
    }

    void RoutingAlgorithm_FindingRoute(object sender, FindingRouteRoutingAlgorithmEventArgs e)
    {
        Collection<string> startPointAdjacentIds = e.RouteSegment.StartPointAdjacentIds;
        Collection<string> endPointAdjacentIds = e.RouteSegment.EndPointAdjacentIds;

        Collection<string> beContainedFeatureIds = new Collection<string>();
        foreach (string featureId in startPointAdjacentIds)
        {
            if (avoidableFeatureIds.Contains(featureId))
            {
                beContainedFeatureIds.Add(featureId);
            }
        }
        foreach (string featureId in endPointAdjacentIds)
        {
            if (avoidableFeatureIds.Contains(featureId))
            {
                beContainedFeatureIds.Add(featureId);
            }
        }

        // Remove the ones that be contained in the avoidable area
        foreach (string id in beContainedFeatureIds)
        {
            if (e.RouteSegment.StartPointAdjacentIds.Contains(id))
            {
                e.RouteSegment.StartPointAdjacentIds.Remove(id);
            }
            if (e.RouteSegment.EndPointAdjacentIds.Contains(id))
            {
                e.RouteSegment.EndPointAdjacentIds.Remove(id);
            }
        }
    }

    private void Route()
    {
        RoutingLayer routingLayer = 
            (RoutingLayer)((LayerOverlay)winformsMap1.Overlays["RoutingOverlay"]).Layers["PHX_RoutingLayer"];

        avoidableFeatureIds.Clear();
        foreach (Feature feature in roadblocksLayer.InternalFeatures)
        {
            avoidableFeatureIds.Add(feature.Id);
        }

        routingLayer.Routes.Clear();
        RoutingResult routingResult = routingEngine.GetRoute(routingLayer.StartPoint, routingLayer.EndPoint);
        if (routingResult.Features.Count == 0)
        {
            MessageBox.Show("No route exists!");
        }
        else
        {
            routingLayer.Routes.Add(routingResult.Route);
        }

        winformsMap1.Refresh(winformsMap1.Overlays["RoutingOverlay"]);
    }

SQLlite datafile is from worldstreetlayers sample application

For routing code - refereed code from RoutingAroundRoadBlock.cs

Datafile
DallasCounty-3857-20170218.sqlite
DallasCounty-3857-20170218_Fast.routable.rtg
DallasCounty-3857-20170218_Fast.routable.shp

Hi Naren,

When you run the data by our generator, you can modify the setting in the WkbConfig.xml file, our default table is osm_road_linestring table, so when your test point in this area it will get result.

After build the rtg file, we also will generate a shape file with extension: routable.shp. You can use this shape file and its rtg file to get routing result.

As below is the simple test sample code based on your code:

        var startPoint = new PointShape(-10784068, 3875497);
        var endPoint = new PointShape(-10769794, 3865255);

        ShapeFileFeatureSource routeableShape = new ShapeFileFeatureSource(@"D:\tmp3\WorldStreetsLayerSDKOnWindows-ForWinForms-master\WorldStreetsLayerSample\App_Data\DallasCounty-3857-20170218.routable.shp");
        RtgRoutingSource routingSource = new RtgRoutingSource(@"D:\tmp3\WorldStreetsLayerSDKOnWindows-ForWinForms-master\WorldStreetsLayerSample\App_Data\DallasCounty-3857-20170218.routable.rtg");

        RoutingEngine routingEngine = new RoutingEngine(routingSource, routeableShape);
        routingEngine.DistanceUnit = DistanceUnit.Meter;
        routingEngine.GeographyUnit = GeographyUnit.Meter;
        
        RoutingResult routingResult = routingEngine.GetRoute(startPoint, endPoint);

It can get result.

Wish that’s helpful.

Regards,

Ethan

Hi Ethan,

What is the formula used to convert latitude/longitude to the point system you mentioned.

    startFeature = new Feature(new PointShape(-96.80629120, 32.79319788));
    endFeature = new Feature(new PointShape(-96.72749863, 32.81208063));

to

    var startPoint = new PointShape(-10784068, 3875497);
    var endPoint = new PointShape(-10769794, 3865255);

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
In my application, I am setting the base map to load with decimal degrees.
winformsMap1.MapUnit = GeographyUnit.DecimalDegree;

When loading each layer - I am changing the projection to
//Sets the projection parameters to go from Geodetic (EPSG 3857) -> decimal degrees to Google Map projection (Spherical Mercator).
Proj4Projection proj = new Proj4Projection();
proj.InternalProjectionParametersString = (Proj4Projection.GetEpsgParametersString(this.Srid));
proj.ExternalProjectionParametersString = Proj4Projection.GetDecimalDegreesParametersString();

        layer.FeatureSource.Projection = proj;
        layer.FeatureSource.Projection.Open();

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
is there a way to make routing to use decimaldegree,
when I tried to generate the rtg with lat/long as the extent - it didn’t produce the proper rtg file.

Thanks in advance for the guidance

Naren

Hi Naren,

I convert the point to 3857 is because your data is 3857, you can see its name is DallasCounty-3857-20170218.sqlite.

You can quickly convert your point from 4326 to 3857 by our Proj4Projection, just like this:

        Proj4Projection proj = new Proj4Projection();
        proj.InternalProjectionParametersString = Proj4Projection.GetDecimalDegreesParametersString();
        proj.ExternalProjectionParametersString = Proj4Projection.GetSphericalMercatorParametersString();
        proj.Open();
        PointShape startPoint = new PointShape(-96.80629120, 32.79319788);
        PointShape start3857Point = proj.ConvertToExternalProjection(startPoint) as PointShape;

The proj you assigned to layer is for render, but for routing I suggest you directly convert the query point to the shape projection. And you can convert the routing result back also.

Regards,

Ethan

In the routing layer applied the projection and now it is working.

routingLayer = new RoutingLayer();

        Proj4Projection proj = new Proj4Projection();
        proj.InternalProjectionParametersString = (Proj4Projection.GetEpsgParametersString(3857));
        proj.ExternalProjectionParametersString = Proj4Projection.GetDecimalDegreesParametersString();

        routingEngine.FeatureSource.Projection = proj;
        routingEngine.FeatureSource.Projection.Open();

        string txtStartCoordinate = "-96.736022,32.860551";
        string txtEndCoordinate = "-96.842102,32.755379";

        string[] startCoordinates = txtStartCoordinate.Split(',');
        PointShape startPoint = new PointShape(double.Parse(startCoordinates[0], CultureInfo.InvariantCulture), double.Parse(startCoordinates[1], CultureInfo.InvariantCulture));
        string[] endCoordinates = txtEndCoordinate.Split(',');
        PointShape endPoint = new PointShape(double.Parse(endCoordinates[0], CultureInfo.InvariantCulture), double.Parse(endCoordinates[1], CultureInfo.InvariantCulture));

        routingLayer.StartPoint = startPoint; // new PointShape(startFeature.GetWellKnownBinary());
        routingLayer.EndPoint = endPoint; // new PointShape(endFeature.GetWellKnownBinary());

Thanks
Naren

Hi Naren,

Thanks for your update, nay question please let us know.

Regards,

Ethan