예제 #1
0
        public ResponseMessage SortPoints([FromBody] PointsVm pointsVm)
        {
            try
            {
                var tspmode     = TTSPmode.tspOpen;
                var gf          = TGISFormat.gfSHP;
                var mTSP        = new List <int>();
                var sortedPoint = new List <GeoNode>();

                //var point = JsonConvert.DeserializeObject<points>(w);

                //var count = point.coordinates.Count - 1;

                var shpfolder = _appSettings.RoutewareSettings.ShapeFolder.Replace("{{region}}", pointsVm.Region);
                var binfolder = _appSettings.RoutewareSettings.BinFolder.Replace("{{region}}", pointsVm.Region);
                var outfolder = _appSettings.RoutewareSettings.OutputFolder.Replace("{{region}}", pointsVm.Region);

                var NW = new TNetwork();
                NW.InitPassword(_appSettings.RoutewareSettings.Password);
                NW.Directory = binfolder;

                NW.Open(true, true, true, 0); // open attributes too, don't cache coord3 and open externID without caching
                NW.OpenLimit(1, 1, false);
                NW.OpenLimit(2, 2, true);
                NW.OpenRoadName(1, false);
                NW.CreateArrayTime(3); // 3 time arrays: 0,1,2
                NW.CreateArrayCost(1); // 1 cost array:  0
                                       // set speed as value based upon road classes 1,2,3,4,6 (store in index 0)
                TRoadClassSpeed rcs = new TRoadClassSpeed();
                rcs[1] = 110;
                rcs[2] = 80;
                rcs[3] = 65;
                rcs[4] = 55;
                rcs[5] = 45;
                rcs[6] = 25;
                NW.CalculateTime(0, rcs);

                TRandom r = new TRandom();
                r.SetSeed(987654321);
                // read speed into ArrayTime[2] from field "speed" in link.dbf
                NW.ReadSpeed(2, shpfolder + "\\link.dbf", 0, "speed", false);

                int link;

                // set speed as random value from 60-100 km/h (store in index 1)
                for (link = 1; link <= NW.LinkCount; link++)
                {
                    NW.SetSpeed(1, link, 60 + 40 * (float)r.NextDouble());
                }

                // set cost as the same as time from index 0
                for (link = 1; link <= NW.LinkCount; link++)
                {
                    NW.SetCost(0, link, NW.GetTime(0, link));
                }
                NW.UpdateAlphas();

                TSpatialSearch ss  = new TSpatialSearch(NW);
                TLocationList  ll  = new TLocationList();
                TBitArray      TBA = new TBitArray(1000);
                TIntegerList   nl  = new TIntegerList();

                if (pointsVm.Nodes != null)
                {
                    for (int i = 0; i < pointsVm.Nodes.Count; i++)
                    {
                        TFloatPoint fp;
                        fp.x = Convert.ToDouble(pointsVm.Nodes[i].Coordinates[0]);
                        fp.y = Convert.ToDouble(pointsVm.Nodes[i].Coordinates[1]);
                        TLocation ll1      = new TLocation();
                        int       side     = 0;
                        double    distance = 0;

                        TFloatPoint fPnew = new TFloatPoint();

                        ss.NearestLocation(fp, out ll1, out side, out distance, out fPnew);
                        ll.Add1(ll1);
                        ll.Add3(fp);
                        ll.Add4(ll1, fp);
                        nl.Add(ss.NearestNodeSimple(fp));
                    }

                    ll.Sort();
                    nl.Sort();
                    nl.RemoveDuplicates();
                }

                TRouteCalc calc = new TRouteCalc(NW, false);
                calc.SetTime(0);
                calc.SetFastest(false);
                calc.MaxSpeed = 110; // 90 > 80 and 110 > 80
                float[][] matrix = calc.Matrix(nl, (tspmode != TTSPmode.tspRoundTrip), false);
                // A faster and straight-line matrix
                // TMatrix Matrix = NW.Matrix(NL,(mode != TTspmode.tspRoundTrip));
                // optimize sequence of matrix
                TTSP tsp = new TTSP {
                    Mode = tspmode
                };
                tsp.Execute(matrix);

                for (int i = 0; i < nl.Count; i++)
                {
                    mTSP.Add(tsp.SortedIndex[i]);
                }

                // Use TDrivingDirections for output
                TGISWrite          output = NW.GISoutputInit(outfolder + "tsp_driving", gf);
                TDrivingDirections dd     = new TDrivingDirections(calc)
                {
                    ConcatenationMode = TConcatenationMode.cmCompact,
                    RoundTrip         = (tspmode == TTSPmode.tspRoundTrip),
                    SortedIndex       = tsp.SortedIndex
                };

                dd.RouteList(output, nl);
                output = NW.GISoutputInit(outfolder + "tsp", gf);
                output.StartHeader(1, TObjectTypes.otPline);
                output.AddField("sequence", TGISField.gfInteger, 0, 0);
                int d = 0;
                if (tspmode != TTSPmode.tspRoundTrip)
                {
                    d = 1;
                }
                for (int i = 0; i < nl.Count - d; i++)
                {
                    int node1 = nl[tsp.SortedIndex[i]];
                    int node2 = i != nl.Count - 1 ? nl[tsp.SortedIndex[i + 1]] : nl[tsp.SortedIndex[0]];

                    calc.Route(node1, node2);
                    TRoute             route = calc.RouteFind(node2);
                    TFloatPointArrayEx list  = NW.GetGISSectionRoute(route);
                    output.AddObject(1, false, i.ToString(CultureInfo.InvariantCulture));
                    output.AddSection(1, ref list);
                }
                output.Close();

                output = NW.GISoutputInit(outfolder + "tsppoint", gf);
                output.StartHeader(1, TObjectTypes.otPoint);
                output.AddField("sequence", TGISField.gfInteger, 0, 0);
                for (int i = 0; i < nl.Count; i++)
                {
                    int         node1 = nl[tsp.SortedIndex[i]];
                    TFloatPoint p1    = NW.Node2Coordinate(node1);
                    output.AddPoint2(p1, i.ToString(CultureInfo.InvariantCulture));
                }
                output.Close();

                for (int i = 0; i < mTSP.Count; i++)
                {
                    sortedPoint.Add(pointsVm.Nodes[mTSP[i]]);
                }

                return(new ResponseMessage {
                    Status = "Ok", Data = sortedPoint
                });
            }
            catch (Exception ex)
            {
                return(new ResponseMessage {
                    Status = "Error", Message = "Error sorting nodes."
                });
            }
        }
예제 #2
0
        private List <Node> GetMST(string region, List <GeoNode> geoNodes)
        {
            try
            {
                _logger?.LogInformation("No. of nodes: " + geoNodes.Count);

                TNetwork NW = new TNetwork();

                var binfolder = _appSettings.RoutewareSettings.BinFolder.Replace("{{region}}", region);

                NW.InitPassword(_appSettings.RoutewareSettings.Password);
                NW.Directory = binfolder;

                NW.Open(false, false, true, 0);

                TIntegerList nodes = new TIntegerList();

                var ss = new TSpatialSearch(NW);

                foreach (var geoNode in geoNodes)
                {
                    var P = new TFloatPoint
                    {
                        x = geoNode.Coordinates[0],
                        y = geoNode.Coordinates[1]
                    };

                    nodes.Add(ss.NearestNodeSimple(P));
                }

                TBitArray links = new TBitArray();

                var calc = new TCalc(NW, false);
                calc.IgnoreOneway = false;

                calc.SteinerTree(nodes, links);

                var steinerTreeFile = _appSettings.RoutewareSettings.SteinerTreeFile.Replace("{{region}}", region);

                if (System.IO.File.Exists(steinerTreeFile))
                {
                    System.IO.File.Delete(steinerTreeFile);
                }

                var geoJsonFile = steinerTreeFile;

                if (System.IO.File.Exists(geoJsonFile + ".geojson"))
                {
                    System.IO.File.Delete(geoJsonFile + ".geojson");
                }

                NW.ExportLinks(geoJsonFile, TGISFormat.gfGeoJSON, null, links);

                var geoJsonData = JsonConvert.DeserializeObject <GeoJosn>(System.IO.File.ReadAllText(geoJsonFile + ".geojson"));

                var listNodes = GetMSTPaths(geoJsonData);

                return(listNodes);
            }
            catch (Exception ex)
            {
                _logger?.LogError(ex, "Error processing nodes.");
                return(null);
            }
        }