Enhanced distance calculation by integrating support for user-specific nodes:
- **Backend**: Updated `DistanceMatrixRepository`, `DistanceApiService`, and related services to handle user-node-specific relationships and unique constraints. - **Database**: Modified `distance_matrix` table schema to include `from_user_node_id` and `to_user_node_id` with exclusive constraints and foreign key references to `sys_user_node`. - **Frontend**: Refined error modal messages and adjusted layout for better usability. Increased pagination size in error logs for improved data display.
This commit is contained in:
parent
dc6ed83853
commit
b99e7b3b4f
11 changed files with 176 additions and 61 deletions
|
|
@ -49,7 +49,7 @@ export default {
|
||||||
props: {isSelected: false, error: this.error},
|
props: {isSelected: false, error: this.error},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Pinia store',
|
title: 'Frontend storage',
|
||||||
component: markRaw(ErrorModalPiniaStore),
|
component: markRaw(ErrorModalPiniaStore),
|
||||||
props: {isSelected: false, error: this.error},
|
props: {isSelected: false, error: this.error},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="no-data">
|
<div v-else class="no-data">
|
||||||
<p>No pinia data</p>
|
<span class="space-around">No frontend data available</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -82,9 +82,13 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-data {
|
.no-data {
|
||||||
padding: 1rem;
|
display: flex;
|
||||||
text-align: center;
|
justify-content: center;
|
||||||
color: #6b7280;
|
align-items: center;
|
||||||
font-style: italic;
|
font-size: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.space-around {
|
||||||
|
margin: 3rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -65,7 +65,7 @@ export default {
|
||||||
const query = {
|
const query = {
|
||||||
searchTerm: '',
|
searchTerm: '',
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 10,
|
pageSize: 20,
|
||||||
}
|
}
|
||||||
await this.fetchData(query);
|
await this.fetchData(query);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,15 @@ public class Distance {
|
||||||
|
|
||||||
private DistanceMatrixState state;
|
private DistanceMatrixState state;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Integer fromNodeId;
|
private Integer fromNodeId;
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private Integer toNodeId;
|
private Integer toNodeId;
|
||||||
|
|
||||||
|
private Integer fromUserNodeId;
|
||||||
|
|
||||||
|
private Integer toUserNodeId;
|
||||||
|
|
||||||
public Integer getFromNodeId() {
|
public Integer getFromNodeId() {
|
||||||
return fromNodeId;
|
return fromNodeId;
|
||||||
}
|
}
|
||||||
|
|
@ -126,4 +129,19 @@ public class Distance {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getFromUserNodeId() {
|
||||||
|
return fromUserNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFromUserNodeId(Integer fromUserNodeId) {
|
||||||
|
this.fromUserNodeId = fromUserNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getToUserNodeId() {
|
||||||
|
return toUserNodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToUserNodeId(Integer toUserNodeId) {
|
||||||
|
this.toUserNodeId = toUserNodeId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ public class Node {
|
||||||
|
|
||||||
private Collection<Integer> outboundCountries;
|
private Collection<Integer> outboundCountries;
|
||||||
|
|
||||||
|
private boolean isUserNode = false;
|
||||||
|
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
@ -176,6 +178,14 @@ public class Node {
|
||||||
this.outboundCountries = outboundCountries;
|
this.outboundCountries = outboundCountries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isUserNode() {
|
||||||
|
return isUserNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserNode(boolean userNode) {
|
||||||
|
isUserNode = userNode;
|
||||||
|
}
|
||||||
|
|
||||||
public String getDebugText() {
|
public String getDebugText() {
|
||||||
return externalMappingId == null ? "\uD83D\uDC64" + name : externalMappingId;
|
return externalMappingId == null ? "\uD83D\uDC64" + name : externalMappingId;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package de.avatic.lcc.repositories;
|
||||||
import de.avatic.lcc.model.db.nodes.Distance;
|
import de.avatic.lcc.model.db.nodes.Distance;
|
||||||
import de.avatic.lcc.model.db.nodes.DistanceMatrixState;
|
import de.avatic.lcc.model.db.nodes.DistanceMatrixState;
|
||||||
import de.avatic.lcc.model.db.nodes.Node;
|
import de.avatic.lcc.model.db.nodes.Node;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
|
@ -24,12 +23,12 @@ public class DistanceMatrixRepository {
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Distance> getDistance(Node src, Node dest) {
|
public Optional<Distance> getDistance(Node src, boolean isUsrFrom, Node dest, boolean isUsrTo) {
|
||||||
String query = "SELECT * FROM distance_matrix WHERE from_node_id = ? AND to_node_id = ? AND state = ?";
|
String query = "SELECT * FROM distance_matrix WHERE ? = ? AND ? = ? AND state = ?";
|
||||||
|
|
||||||
var distance = jdbcTemplate.query(query, new DistanceMapper(), src.getId(), dest.getId(), DistanceMatrixState.VALID.name());
|
var distance = jdbcTemplate.query(query, new DistanceMapper(), isUsrFrom ? "from_user_node_id" : "from_node_id", src.getId(), isUsrTo ? "to_user_node_id" : "to_node_id", dest.getId(), DistanceMatrixState.VALID.name());
|
||||||
|
|
||||||
if(distance.isEmpty())
|
if (distance.isEmpty())
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
return Optional.of(distance.getFirst());
|
return Optional.of(distance.getFirst());
|
||||||
|
|
@ -37,26 +36,29 @@ public class DistanceMatrixRepository {
|
||||||
|
|
||||||
public void saveDistance(Distance distance) {
|
public void saveDistance(Distance distance) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// First, check if an entry already exists
|
// First, check if an entry already exists
|
||||||
String checkQuery = "SELECT id FROM distance_matrix WHERE from_node_id = ? AND to_node_id = ?";
|
String checkQuery = "SELECT id FROM distance_matrix WHERE ? = ? AND ? = ?";
|
||||||
var existingIds = jdbcTemplate.query(checkQuery,
|
var existingIds = jdbcTemplate.query(checkQuery,
|
||||||
(rs, rowNum) -> rs.getInt("id"),
|
(rs, rowNum) -> rs.getInt("id"),
|
||||||
distance.getFromNodeId(),
|
distance.getFromUserNodeId() != null ? "from_user_node_id" : "from_node_id",
|
||||||
distance.getToNodeId());
|
distance.getFromUserNodeId() != null ? distance.getFromUserNodeId() : distance.getFromNodeId(),
|
||||||
|
distance.getToUserNodeId() != null ? "to_user_node_id" : "to_node_id",
|
||||||
|
distance.getToUserNodeId() != null ? distance.getToUserNodeId() : distance.getToNodeId());
|
||||||
|
|
||||||
if (!existingIds.isEmpty()) {
|
if (!existingIds.isEmpty()) {
|
||||||
// Update existing entry
|
// Update existing entry
|
||||||
String updateQuery = """
|
String updateQuery = """
|
||||||
UPDATE distance_matrix
|
UPDATE distance_matrix
|
||||||
SET from_geo_lat = ?,
|
SET from_geo_lat = ?,
|
||||||
from_geo_lng = ?,
|
from_geo_lng = ?,
|
||||||
to_geo_lat = ?,
|
to_geo_lat = ?,
|
||||||
to_geo_lng = ?,
|
to_geo_lng = ?,
|
||||||
distance = ?,
|
distance = ?,
|
||||||
state = ?,
|
state = ?,
|
||||||
updated_at = ?
|
updated_at = ?
|
||||||
WHERE from_node_id = ? AND to_node_id = ?
|
WHERE ? = ? AND ? = ?
|
||||||
""";
|
""";
|
||||||
|
|
||||||
jdbcTemplate.update(updateQuery,
|
jdbcTemplate.update(updateQuery,
|
||||||
distance.getFromGeoLat(),
|
distance.getFromGeoLat(),
|
||||||
|
|
@ -66,22 +68,26 @@ public class DistanceMatrixRepository {
|
||||||
distance.getDistance(),
|
distance.getDistance(),
|
||||||
distance.getState().name(),
|
distance.getState().name(),
|
||||||
distance.getUpdatedAt(),
|
distance.getUpdatedAt(),
|
||||||
distance.getFromNodeId(),
|
distance.getFromUserNodeId() != null ? "from_user_node_id" : "from_node_id",
|
||||||
distance.getToNodeId());
|
distance.getFromUserNodeId() != null ? distance.getFromUserNodeId() : distance.getFromNodeId(),
|
||||||
|
distance.getToUserNodeId() != null ? "to_user_node_id" : "to_node_id",
|
||||||
|
distance.getToUserNodeId() != null ? distance.getToUserNodeId() : distance.getToNodeId());
|
||||||
|
|
||||||
logger.info("Updated existing distance entry for nodes {} -> {}",
|
logger.info("Updated existing distance entry for nodes {} -> {}",
|
||||||
distance.getFromNodeId(), distance.getToNodeId());
|
distance.getFromNodeId(), distance.getToNodeId());
|
||||||
} else {
|
} else {
|
||||||
// Insert new entry
|
// Insert new entry
|
||||||
String insertQuery = """
|
String insertQuery = """
|
||||||
INSERT INTO distance_matrix
|
INSERT INTO distance_matrix
|
||||||
(from_node_id, to_node_id, from_geo_lat, from_geo_lng, to_geo_lat, to_geo_lng, distance, state, updated_at)
|
(from_node_id, to_node_id, from_user_node_id, to_user_node_id, from_geo_lat, from_geo_lng, to_geo_lat, to_geo_lng, distance, state, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""";
|
""";
|
||||||
|
|
||||||
jdbcTemplate.update(insertQuery,
|
jdbcTemplate.update(insertQuery,
|
||||||
distance.getFromNodeId(),
|
distance.getFromNodeId(),
|
||||||
distance.getToNodeId(),
|
distance.getToNodeId(),
|
||||||
|
distance.getFromUserNodeId(),
|
||||||
|
distance.getToUserNodeId(),
|
||||||
distance.getFromGeoLat(),
|
distance.getFromGeoLat(),
|
||||||
distance.getFromGeoLng(),
|
distance.getFromGeoLng(),
|
||||||
distance.getToGeoLat(),
|
distance.getToGeoLat(),
|
||||||
|
|
@ -107,6 +113,8 @@ public class DistanceMatrixRepository {
|
||||||
|
|
||||||
entity.setFromNodeId(rs.getInt("from_node_id"));
|
entity.setFromNodeId(rs.getInt("from_node_id"));
|
||||||
entity.setToNodeId(rs.getInt("to_node_id"));
|
entity.setToNodeId(rs.getInt("to_node_id"));
|
||||||
|
entity.setFromNodeId(rs.getInt("from_user_node_id"));
|
||||||
|
entity.setToNodeId(rs.getInt("to_user_node_id"));
|
||||||
entity.setDistance(rs.getBigDecimal("distance"));
|
entity.setDistance(rs.getBigDecimal("distance"));
|
||||||
entity.setFromGeoLng(rs.getBigDecimal("from_geo_lng"));
|
entity.setFromGeoLng(rs.getBigDecimal("from_geo_lng"));
|
||||||
entity.setFromGeoLat(rs.getBigDecimal("from_geo_lat"));
|
entity.setFromGeoLat(rs.getBigDecimal("from_geo_lat"));
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,8 @@ public class UserNodeRepository {
|
||||||
node.setIntermediate(false);
|
node.setIntermediate(false);
|
||||||
node.setSource(true);
|
node.setSource(true);
|
||||||
|
|
||||||
|
node.setUserNode(true);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package de.avatic.lcc.service.api;
|
||||||
import de.avatic.lcc.model.azuremaps.route.RouteDirectionsResponse;
|
import de.avatic.lcc.model.azuremaps.route.RouteDirectionsResponse;
|
||||||
import de.avatic.lcc.model.db.nodes.Distance;
|
import de.avatic.lcc.model.db.nodes.Distance;
|
||||||
import de.avatic.lcc.model.db.nodes.DistanceMatrixState;
|
import de.avatic.lcc.model.db.nodes.DistanceMatrixState;
|
||||||
|
import de.avatic.lcc.model.db.nodes.Location;
|
||||||
import de.avatic.lcc.model.db.nodes.Node;
|
import de.avatic.lcc.model.db.nodes.Node;
|
||||||
import de.avatic.lcc.repositories.DistanceMatrixRepository;
|
import de.avatic.lcc.repositories.DistanceMatrixRepository;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
@ -13,7 +14,6 @@ import org.springframework.web.client.RestTemplate;
|
||||||
import org.springframework.web.util.UriComponentsBuilder;
|
import org.springframework.web.util.UriComponentsBuilder;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.net.URI;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
|
@ -35,7 +35,27 @@ public class DistanceApiService {
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Distance> getDistance(Node from, Node to) {
|
public Optional<Integer> getDistance(Location from, Location to) {
|
||||||
|
if (from == null || to == null) {
|
||||||
|
logger.warn("Source or destination location is null");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from.getLatitude() == null || from.getLongitude() == null ||
|
||||||
|
to.getLatitude() == null || to.getLongitude() == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteDirectionsResponse response = fetchDistanceFromAzureMaps(BigDecimal.valueOf(from.getLatitude()), BigDecimal.valueOf(from.getLongitude()), BigDecimal.valueOf(to.getLatitude()), BigDecimal.valueOf(to.getLongitude()));
|
||||||
|
|
||||||
|
if (response != null && response.getRoutes() != null && !response.getRoutes().isEmpty()) {
|
||||||
|
return Optional.of(response.getRoutes().getFirst().getSummary().getLengthInMeters());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Distance> getDistance(Node from, boolean isUsrFrom, Node to, boolean isUsrTo) {
|
||||||
|
|
||||||
if (from == null || to == null) {
|
if (from == null || to == null) {
|
||||||
logger.warn("Source or destination node is null");
|
logger.warn("Source or destination node is null");
|
||||||
|
|
@ -48,7 +68,7 @@ public class DistanceApiService {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Distance> cachedDistance = distanceMatrixRepository.getDistance(from, to);
|
Optional<Distance> cachedDistance = distanceMatrixRepository.getDistance(from, isUsrFrom, to, isUsrTo);
|
||||||
|
|
||||||
if (cachedDistance.isPresent()) {
|
if (cachedDistance.isPresent()) {
|
||||||
logger.debug("Found cached distance from node {} to node {}", from.getId(), to.getId());
|
logger.debug("Found cached distance from node {} to node {}", from.getId(), to.getId());
|
||||||
|
|
@ -56,7 +76,7 @@ public class DistanceApiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("Fetching distance from Azure Maps for nodes {} to {}", from.getId(), to.getId());
|
logger.debug("Fetching distance from Azure Maps for nodes {} to {}", from.getId(), to.getId());
|
||||||
Optional<Distance> fetchedDistance = fetchDistanceFromAzureMaps(from, to);
|
Optional<Distance> fetchedDistance = fetchDistanceFromAzureMaps(from, isUsrFrom, to, isUsrTo);
|
||||||
|
|
||||||
if (fetchedDistance.isPresent()) {
|
if (fetchedDistance.isPresent()) {
|
||||||
distanceMatrixRepository.saveDistance(fetchedDistance.get());
|
distanceMatrixRepository.saveDistance(fetchedDistance.get());
|
||||||
|
|
@ -66,25 +86,45 @@ public class DistanceApiService {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Distance> fetchDistanceFromAzureMaps(Node from, Node to) {
|
private RouteDirectionsResponse fetchDistanceFromAzureMaps(BigDecimal fromLat, BigDecimal fromLng, BigDecimal toLat, BigDecimal toLng) {
|
||||||
try {
|
String url = UriComponentsBuilder.fromUriString(AZURE_MAPS_ROUTE_API)
|
||||||
String url = UriComponentsBuilder.fromUriString(AZURE_MAPS_ROUTE_API)
|
.queryParam("api-version", "1.0")
|
||||||
.queryParam("api-version", "1.0")
|
.queryParam("subscription-key", subscriptionKey)
|
||||||
.queryParam("subscription-key", subscriptionKey)
|
.queryParam("query", String.format("%s,%s:%s,%s",
|
||||||
.queryParam("query", String.format("%s,%s:%s,%s",
|
fromLat, fromLng,
|
||||||
from.getGeoLat(), from.getGeoLng(),
|
toLat, toLng))
|
||||||
to.getGeoLat(), to.getGeoLng()))
|
.encode()
|
||||||
.encode()
|
.toUriString();
|
||||||
.toUriString();
|
|
||||||
|
|
||||||
RouteDirectionsResponse response = restTemplate.getForObject(url, RouteDirectionsResponse.class);
|
return restTemplate.getForObject(url, RouteDirectionsResponse.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Distance> fetchDistanceFromAzureMaps(Node from, boolean isUsrFrom, Node to, boolean isUsrTo) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
RouteDirectionsResponse response = fetchDistanceFromAzureMaps(from.getGeoLat(), from.getGeoLng(), to.getGeoLat(), to.getGeoLng());
|
||||||
|
|
||||||
if (response != null && response.getRoutes() != null && !response.getRoutes().isEmpty()) {
|
if (response != null && response.getRoutes() != null && !response.getRoutes().isEmpty()) {
|
||||||
Integer distanceInMeters = response.getRoutes().getFirst().getSummary().getLengthInMeters();
|
Integer distanceInMeters = response.getRoutes().getFirst().getSummary().getLengthInMeters();
|
||||||
|
|
||||||
Distance distance = new Distance();
|
Distance distance = new Distance();
|
||||||
distance.setFromNodeId(from.getId());
|
|
||||||
distance.setToNodeId(to.getId());
|
if (isUsrFrom) {
|
||||||
|
distance.setFromUserNodeId(from.getId());
|
||||||
|
distance.setFromNodeId(null);
|
||||||
|
} else {
|
||||||
|
distance.setFromUserNodeId(null);
|
||||||
|
distance.setFromNodeId(from.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUsrTo) {
|
||||||
|
distance.setToUserNodeId(to.getId());
|
||||||
|
distance.setToNodeId(null);
|
||||||
|
} else {
|
||||||
|
distance.setToUserNodeId(null);
|
||||||
|
distance.setToNodeId(from.getId());
|
||||||
|
}
|
||||||
|
|
||||||
distance.setFromGeoLat(from.getGeoLat());
|
distance.setFromGeoLat(from.getGeoLat());
|
||||||
distance.setFromGeoLng(from.getGeoLng());
|
distance.setFromGeoLng(from.getGeoLng());
|
||||||
distance.setToGeoLat(to.getGeoLat());
|
distance.setToGeoLat(to.getGeoLat());
|
||||||
|
|
|
||||||
|
|
@ -13,26 +13,34 @@ import org.springframework.stereotype.Service;
|
||||||
public class DistanceService {
|
public class DistanceService {
|
||||||
|
|
||||||
private static final double EARTH_RADIUS = 6371.0;
|
private static final double EARTH_RADIUS = 6371.0;
|
||||||
private final DistanceMatrixRepository distanceMatrixRepository;
|
|
||||||
private final CountryRepository countryRepository;
|
private final CountryRepository countryRepository;
|
||||||
private final DistanceApiService distanceApiService;
|
private final DistanceApiService distanceApiService;
|
||||||
|
|
||||||
public DistanceService(DistanceMatrixRepository distanceMatrixRepository, CountryRepository countryRepository, DistanceApiService distanceApiService) {
|
public DistanceService(CountryRepository countryRepository, DistanceApiService distanceApiService) {
|
||||||
this.distanceMatrixRepository = distanceMatrixRepository;
|
|
||||||
this.countryRepository = countryRepository;
|
this.countryRepository = countryRepository;
|
||||||
this.distanceApiService = distanceApiService;
|
this.distanceApiService = distanceApiService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getDistance(Integer srcCountryId, Location src, Integer destCountryId, Location dest, boolean fast) {
|
||||||
|
if (fast) return getDistanceFast(srcCountryId, src, destCountryId, dest);
|
||||||
|
|
||||||
|
var distance = distanceApiService.getDistance(src, dest);
|
||||||
|
if (distance.isEmpty()) return getDistanceFast(srcCountryId, src, destCountryId, dest);
|
||||||
|
|
||||||
|
return distance.map(value -> value/1000).orElse(0);
|
||||||
|
}
|
||||||
|
|
||||||
public double getDistance(Node src, Node dest, boolean fast) {
|
public double getDistance(Node src, Node dest, boolean fast) {
|
||||||
if (fast) return getDistanceFast(src, dest);
|
if (fast) return getDistanceFast(src, dest);
|
||||||
|
|
||||||
var distance = distanceApiService.getDistance(src, dest);
|
var distance = distanceApiService.getDistance(src, src.isUserNode(), dest, dest.isUserNode());
|
||||||
if (distance.isEmpty()) return getDistanceFast(src, dest);
|
if (distance.isEmpty()) return getDistanceFast(src, dest);
|
||||||
|
|
||||||
return distance.map(value -> value.getDistance().intValue()/1000).orElse(0);
|
return distance.map(value -> value.getDistance().intValue()/1000).orElse(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getDistanceFast(Integer srcCountryId, Location src, Integer destCountryId, Location dest ) {
|
|
||||||
|
public double getDistanceFast(Integer srcCountryId, Location src, Integer destCountryId, Location dest ) {
|
||||||
double srcLatitudeRadians = Math.toRadians(src.getLatitude());
|
double srcLatitudeRadians = Math.toRadians(src.getLatitude());
|
||||||
double srcLongitudeRad = Math.toRadians(src.getLongitude());
|
double srcLongitudeRad = Math.toRadians(src.getLongitude());
|
||||||
double destLatitudeRadians = Math.toRadians(dest.getLatitude());
|
double destLatitudeRadians = Math.toRadians(dest.getLatitude());
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ public class RoutingService {
|
||||||
|
|
||||||
public List<RouteInformation> findRoutes(Node destination, Node source, boolean sourceIsUserNode) {
|
public List<RouteInformation> findRoutes(Node destination, Node source, boolean sourceIsUserNode) {
|
||||||
List<RouteInformation> routeInformation = new ArrayList<>();
|
List<RouteInformation> routeInformation = new ArrayList<>();
|
||||||
TemporaryContainer container = new TemporaryContainer(source, destination);
|
TemporaryContainer container = new TemporaryContainer(source, destination, sourceIsUserNode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the source and destination node from database.
|
* Get the source and destination node from database.
|
||||||
|
|
@ -740,6 +740,7 @@ public class RoutingService {
|
||||||
* Source and destination node
|
* Source and destination node
|
||||||
*/
|
*/
|
||||||
private final Node source;
|
private final Node source;
|
||||||
|
private final boolean sourceIsUserNode;
|
||||||
private final Node destination;
|
private final Node destination;
|
||||||
private final Map<Integer, List<List<Node>>> chains = new HashMap<>();
|
private final Map<Integer, List<List<Node>>> chains = new HashMap<>();
|
||||||
/*
|
/*
|
||||||
|
|
@ -752,8 +753,9 @@ public class RoutingService {
|
||||||
private Map<Integer, List<ContainerRate>> postRuns;
|
private Map<Integer, List<ContainerRate>> postRuns;
|
||||||
private MatrixRate sourceMatrixRate;
|
private MatrixRate sourceMatrixRate;
|
||||||
|
|
||||||
public TemporaryContainer(Node source, Node destination) {
|
public TemporaryContainer(Node source, Node destination, boolean sourceIsUserNode) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
|
this.sourceIsUserNode = sourceIsUserNode;
|
||||||
this.destination = destination;
|
this.destination = destination;
|
||||||
this.mainRuns = null;
|
this.mainRuns = null;
|
||||||
this.postRuns = null;
|
this.postRuns = null;
|
||||||
|
|
@ -821,6 +823,10 @@ public class RoutingService {
|
||||||
public void setChain(Integer id, List<List<Node>> chain) {
|
public void setChain(Integer id, List<List<Node>> chain) {
|
||||||
this.chains.put(id, chain);
|
this.chains.put(id, chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSourceIsUserNode() {
|
||||||
|
return sourceIsUserNode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Renderer(text = "getFullDebugText()")
|
@Renderer(text = "getFullDebugText()")
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import de.avatic.lcc.repositories.premise.RouteNodeRepository;
|
||||||
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
import de.avatic.lcc.repositories.properties.PropertyRepository;
|
||||||
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
|
import de.avatic.lcc.repositories.rates.ContainerRateRepository;
|
||||||
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
import de.avatic.lcc.repositories.rates.MatrixRateRepository;
|
||||||
|
import de.avatic.lcc.repositories.users.UserNodeRepository;
|
||||||
import de.avatic.lcc.service.calculation.DistanceService;
|
import de.avatic.lcc.service.calculation.DistanceService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
|
@ -38,8 +39,9 @@ public class RouteSectionCostCalculationService {
|
||||||
private final PropertyRepository propertyRepository;
|
private final PropertyRepository propertyRepository;
|
||||||
private final ChangeRiskFactorCalculationService changeRiskFactorCalculationService;
|
private final ChangeRiskFactorCalculationService changeRiskFactorCalculationService;
|
||||||
private final NodeRepository nodeRepository;
|
private final NodeRepository nodeRepository;
|
||||||
|
private final UserNodeRepository userNodeRepository;
|
||||||
|
|
||||||
public RouteSectionCostCalculationService(ContainerRateRepository containerRateRepository, MatrixRateRepository matrixRateRepository, RouteNodeRepository routeNodeRepository, DistanceService distanceService, PropertyRepository propertyRepository, ChangeRiskFactorCalculationService changeRiskFactorCalculationService, NodeRepository nodeRepository) {
|
public RouteSectionCostCalculationService(ContainerRateRepository containerRateRepository, MatrixRateRepository matrixRateRepository, RouteNodeRepository routeNodeRepository, DistanceService distanceService, PropertyRepository propertyRepository, ChangeRiskFactorCalculationService changeRiskFactorCalculationService, NodeRepository nodeRepository, UserNodeRepository userNodeRepository) {
|
||||||
this.containerRateRepository = containerRateRepository;
|
this.containerRateRepository = containerRateRepository;
|
||||||
this.matrixRateRepository = matrixRateRepository;
|
this.matrixRateRepository = matrixRateRepository;
|
||||||
this.routeNodeRepository = routeNodeRepository;
|
this.routeNodeRepository = routeNodeRepository;
|
||||||
|
|
@ -47,6 +49,7 @@ public class RouteSectionCostCalculationService {
|
||||||
this.propertyRepository = propertyRepository;
|
this.propertyRepository = propertyRepository;
|
||||||
this.changeRiskFactorCalculationService = changeRiskFactorCalculationService;
|
this.changeRiskFactorCalculationService = changeRiskFactorCalculationService;
|
||||||
this.nodeRepository = nodeRepository;
|
this.nodeRepository = nodeRepository;
|
||||||
|
this.userNodeRepository = userNodeRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CalculationJobRouteSection doD2dCalculation(Integer setId, Integer periodId, Premise premise, Destination destination, ContainerCalculationResult containerCalculation) {
|
public CalculationJobRouteSection doD2dCalculation(Integer setId, Integer periodId, Premise premise, Destination destination, ContainerCalculationResult containerCalculation) {
|
||||||
|
|
@ -274,9 +277,25 @@ public class RouteSectionCostCalculationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getDistance(RouteNode fromNode, RouteNode toNode) {
|
private double getDistance(RouteNode fromNode, RouteNode toNode) {
|
||||||
return distanceService.getDistanceFast(
|
|
||||||
fromNode.getCountryId(), new Location(fromNode.getGeoLng().doubleValue(), fromNode.getGeoLat().doubleValue()),
|
if(fromNode.getOutdated() || toNode.getOutdated()) {
|
||||||
toNode.getCountryId(), new Location(toNode.getGeoLng().doubleValue(), toNode.getGeoLat().doubleValue()));
|
return distanceService.getDistance(
|
||||||
|
fromNode.getCountryId(), new Location(fromNode.getGeoLng().doubleValue(), fromNode.getGeoLat().doubleValue()),
|
||||||
|
toNode.getCountryId(), new Location(toNode.getGeoLng().doubleValue(), toNode.getGeoLat().doubleValue()), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var optSrcNode = fromNode.getNodeId() == null ? userNodeRepository.getById(fromNode.getUserNodeId()) : nodeRepository.getById(fromNode.getNodeId());
|
||||||
|
var optDestNode = toNode.getNodeId() == null ? userNodeRepository.getById(toNode.getUserNodeId()) : nodeRepository.getById(toNode.getNodeId());
|
||||||
|
|
||||||
|
if(optSrcNode.isEmpty() ) {
|
||||||
|
throw new NoSuchElementException("Source node not found for route section " + fromNode.getName());
|
||||||
|
}
|
||||||
|
if(optDestNode.isEmpty() ) {
|
||||||
|
throw new NoSuchElementException("Destination node not found for route section" + toNode.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return distanceService.getDistance(optSrcNode.get(), optDestNode.get(), false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue