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." }); } }