package com.deliveryproject.easydelivery; import com.deliveryproject.easydelivery.Models.Coordinate; import com.deliveryproject.easydelivery.Models.OSMRClass.Intersection; import com.deliveryproject.easydelivery.Models.OSMRClass.Root; import com.deliveryproject.easydelivery.Models.OSMRClass.Step; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.web.bind.annotation.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.List; @CrossOrigin @RestController public class MainController { //@PreAuthorize("hasRole('User')") @GetMapping("/route/nodes") @ResponseBody public ArrayList> getNodesBetweenTwoCoordinates(@RequestParam double lon1, @RequestParam double lat1, @RequestParam double lon2, @RequestParam double lat2) throws IOException { System.out.println(lon1); String url = "http://router.project-osrm.org/route/v1/driving/" + lon1 + "," + lat1 + ";" + lon2 + "," + lat2 + "?steps=true&geometries=geojson"; System.out.println(url); URL osrmEndpoint = new URL(url); HttpURLConnection connection = (HttpURLConnection) osrmEndpoint.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("Content-Type", "application/json"); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); ObjectMapper om = new ObjectMapper(); Root root = om.readValue(response.toString(), Root.class); ArrayList steps = root.routes.get(0).legs.get(0).steps; ArrayList> coordinates = new ArrayList<>(); for (Step step : steps) { ArrayList intersections = step.intersections; for (Intersection intersection : intersections) { ArrayList location = new ArrayList<>(); location.add(intersection.location.get(1)); location.add(intersection.location.get(0)); coordinates.add(location); } } System.out.println(coordinates); return coordinates; } @GetMapping("/optimize-delivery-route") @ResponseBody public List optimizeDeliveryRoute(List coordinates) { List optimizedRoute = new ArrayList<>(); List optimizedRouteCoordinates = new ArrayList<>(); boolean[] visited = new boolean[coordinates.size()]; int currentCoordinateIndex = 0; optimizedRoute.add(currentCoordinateIndex); visited[currentCoordinateIndex] = true; while (optimizedRoute.size() < coordinates.size()) { double minDistance = Double.MAX_VALUE; int nearestCoordinateIndex = -1; for (int i = 0; i < coordinates.size(); i++) { if (!visited[i]) { double distance = calculateDistance(coordinates.get(currentCoordinateIndex), coordinates.get(i)); if (distance < minDistance) { minDistance = distance; nearestCoordinateIndex = i; } } } optimizedRoute.add(nearestCoordinateIndex); visited[nearestCoordinateIndex] = true; currentCoordinateIndex = nearestCoordinateIndex; } for (Integer integer : optimizedRoute) { optimizedRouteCoordinates.add(coordinates.get(integer)); } return optimizedRouteCoordinates; } private double calculateDistance(Coordinate c1, Coordinate c2) { ArrayList> nodes; try { nodes = getNodesBetweenTwoCoordinates(c1.lat, c1.lon, c2.lat, c2.lon); } catch (IOException e) { e.printStackTrace(); return Double.MAX_VALUE; } double sumDistance = 0.0; for (int i = 0; i < nodes.size() - 1; i++) { ArrayList current = nodes.get(i); ArrayList next = nodes.get(i + 1); double dx = next.get(0) - current.get(0); double dy = next.get(1) - current.get(1); double distance = Math.sqrt(dx * dx + dy * dy); sumDistance += distance; } return sumDistance; } }