From 27ce113d62d88413faf54eab614bedcc724836a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A5=D0=BE=D1=80=D0=BE=D1=88=D0=B0=D0=B2=D0=B8=D0=BD=20?= =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9=20=D0=9A=D0=BE=D0=BD?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BD=D1=82=D0=B8=D0=BD=D0=BE=D0=B2=D0=B8?= =?UTF-8?q?=D1=87?= Date: Sat, 30 Sep 2023 11:43:54 +0700 Subject: [PATCH] =?UTF-8?q?WHERETOGO-0011=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=BF=D0=BE=D0=BB=D0=B5=20'duration?= =?UTF-8?q?'=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=83=D1=89=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D0=B2=D1=83=D1=8E=D1=89=D0=B8=D1=85=20=D0=BC=D0=B5=D1=81=D1=82?= =?UTF-8?q?=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5=20=D0=B4=D0=B0=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- where-to-go-back/README.md | 4 +- .../ru/nsu/fit/wheretogo/dto/BaseDTO.java | 6 +- .../fit/wheretogo/dto/place/CategoryDTO.java | 2 + .../wheretogo/dto/place/PlaceBriefDTO.java | 20 +- .../dto/place/PlaceDescriptionDTO.java | 28 +- .../nsu/fit/wheretogo/dto/user/ScoreDTO.java | 14 +- .../fit/wheretogo/dto/user/StayPointDTO.java | 14 +- .../nsu/fit/wheretogo/dto/user/UserDTO.java | 14 +- .../nsu/fit/wheretogo/entity/place/Place.java | 3 + .../V16__Add_Time_Duration_To_Places.sql | 4 + .../migration/V17__Add_Places_Durations.sql | 123 ++++ .../db/migration/V18__Update_Places_View.sql | 9 + .../migration/V19__Update_Place_Functions.sql | 647 ++++++++++++++++++ where-to-go-ui/app/build.gradle | 7 +- .../nsu/fit/wheretogo/model/entity/Place.java | 12 +- .../main/res/drawable-v24/make_path_btn.png | Bin 0 -> 1715 bytes .../main/res/drawable-v24/make_path_field.png | Bin 0 -> 45292 bytes .../src/main/res/drawable-v24/recommnd.png | Bin 7784 -> 8659 bytes .../res/drawable-v24/recommnd_notactive.png | Bin 7377 -> 6133 bytes .../src/main/res/layout/activity_for_you.xml | 300 ++++---- where-to-go-ui/build.gradle | 4 +- 21 files changed, 988 insertions(+), 223 deletions(-) create mode 100644 where-to-go-back/src/main/resources/db/migration/V16__Add_Time_Duration_To_Places.sql create mode 100644 where-to-go-back/src/main/resources/db/migration/V17__Add_Places_Durations.sql create mode 100644 where-to-go-back/src/main/resources/db/migration/V18__Update_Places_View.sql create mode 100644 where-to-go-back/src/main/resources/db/migration/V19__Update_Place_Functions.sql create mode 100644 where-to-go-ui/app/src/main/res/drawable-v24/make_path_btn.png create mode 100644 where-to-go-ui/app/src/main/res/drawable-v24/make_path_field.png diff --git a/where-to-go-back/README.md b/where-to-go-back/README.md index 23cc3de..9da8814 100644 --- a/where-to-go-back/README.md +++ b/where-to-go-back/README.md @@ -32,7 +32,7 @@ Для проверки тестового покрытия кода необходимо провести сборку проекта: - mvn clean install + mvn clean package А затем вызвать sonar с помощью: @@ -40,7 +40,7 @@ Также можно использовать комбинированную команду: - mvn clean install sonar:sonar + mvn clean package sonar:sonar ### Docker-контейнер: diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/BaseDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/BaseDTO.java index 544dc1b..855aa8e 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/BaseDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/BaseDTO.java @@ -1,6 +1,7 @@ package ru.nsu.fit.wheretogo.dto; import lombok.Getter; +import lombok.Setter; import javax.validation.constraints.NotNull; @@ -8,13 +9,10 @@ * Базовая модель DTO */ @Getter +@Setter public abstract class BaseDTO { @NotNull protected Long id; - public void setId(Long id) { - this.id = id; - } - } diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/CategoryDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/CategoryDTO.java index e1d351d..327f26f 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/CategoryDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/CategoryDTO.java @@ -1,6 +1,7 @@ package ru.nsu.fit.wheretogo.dto.place; import lombok.Getter; +import lombok.Setter; import ru.nsu.fit.wheretogo.dto.BaseDTO; import ru.nsu.fit.wheretogo.entity.place.Category; @@ -8,6 +9,7 @@ import javax.validation.constraints.Size; @Getter +@Setter public class CategoryDTO extends BaseDTO { @NotNull(message = "Enter category name") diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceBriefDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceBriefDTO.java index 679f5bd..fb0ce34 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceBriefDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceBriefDTO.java @@ -1,18 +1,21 @@ package ru.nsu.fit.wheretogo.dto.place; import lombok.Getter; +import lombok.Setter; import ru.nsu.fit.wheretogo.entity.place.Coordinates; import ru.nsu.fit.wheretogo.entity.place.Place; import java.util.List; @Getter +@Setter public class PlaceBriefDTO extends PlaceDTO { private String name; private Coordinates coordinates; private String thumbnailLink; private List categories; + private Integer duration; public static PlaceBriefDTO getFromEntity(Place entity) { if (entity == null) { @@ -27,23 +30,8 @@ public static PlaceBriefDTO getFromEntity(Place entity) { dto.setCoordinates(entity.getCoordinates()); dto.setThumbnailLink(entity.getThumbnail()); dto.setCategories(categories); + dto.setDuration(entity.getDuration()); return dto; } - - public void setName(String name) { - this.name = name; - } - - public void setCoordinates(Coordinates coordinates) { - this.coordinates = coordinates; - } - - public void setThumbnailLink(String thumbnailLink) { - this.thumbnailLink = thumbnailLink; - } - - public void setCategories(List categories) { - this.categories = categories; - } } diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceDescriptionDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceDescriptionDTO.java index de407b1..fae8c6f 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceDescriptionDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/place/PlaceDescriptionDTO.java @@ -1,6 +1,7 @@ package ru.nsu.fit.wheretogo.dto.place; import lombok.Getter; +import lombok.Setter; import ru.nsu.fit.wheretogo.entity.place.Coordinates; import ru.nsu.fit.wheretogo.entity.place.Place; @@ -8,6 +9,7 @@ import java.util.List; @Getter +@Setter public class PlaceDescriptionDTO extends PlaceDTO { private String name; @@ -16,6 +18,7 @@ public class PlaceDescriptionDTO extends PlaceDTO { private String thumbnail; private Instant uploadedAt; private List categories; + private Integer duration; public static PlaceDescriptionDTO getFromEntity(Place entity) { if (entity == null) { @@ -32,31 +35,8 @@ public static PlaceDescriptionDTO getFromEntity(Place entity) { dto.setThumbnail(entity.getThumbnail()); dto.setUploadedAt(entity.getUploadedAt()); dto.setCategories(categories); + dto.setDuration(entity.getDuration()); return dto; } - - public void setName(String name) { - this.name = name; - } - - public void setDescription(String description) { - this.description = description; - } - - public void setCoordinates(Coordinates coordinates) { - this.coordinates = coordinates; - } - - public void setThumbnail(String thumbnail) { - this.thumbnail = thumbnail; - } - - public void setUploadedAt(Instant uploadedAt) { - this.uploadedAt = uploadedAt; - } - - public void setCategories(List categories) { - this.categories = categories; - } } diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/ScoreDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/ScoreDTO.java index 62b675e..6fffd1a 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/ScoreDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/ScoreDTO.java @@ -1,6 +1,7 @@ package ru.nsu.fit.wheretogo.dto.user; import lombok.Getter; +import lombok.Setter; import ru.nsu.fit.wheretogo.dto.BaseDTO; import ru.nsu.fit.wheretogo.entity.score.Score; @@ -8,6 +9,7 @@ import javax.validation.constraints.Min; @Getter +@Setter public class ScoreDTO extends BaseDTO { private Long author; @@ -29,16 +31,4 @@ public static ScoreDTO getFromEntity(Score score) { return dto; } - - public void setAuthor(Long author) { - this.author = author; - } - - public void setPlace(Long place) { - this.place = place; - } - - public void setScore(Integer score) { - this.score = score; - } } diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/StayPointDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/StayPointDTO.java index 31397da..abf16e9 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/StayPointDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/StayPointDTO.java @@ -1,10 +1,12 @@ package ru.nsu.fit.wheretogo.dto.user; import lombok.Getter; +import lombok.Setter; import ru.nsu.fit.wheretogo.dto.BaseDTO; import ru.nsu.fit.wheretogo.entity.place.StayPoint; @Getter +@Setter public class StayPointDTO extends BaseDTO { private double latitude; @@ -24,16 +26,4 @@ public static StayPointDTO getFromEntity(StayPoint stayPoint) { return dto; } - - public void setLatitude(double latitude) { - this.latitude = latitude; - } - - public void setLongitude(double longitude) { - this.longitude = longitude; - } - - public void setUserId(Long userId) { - this.userId = userId; - } } diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/UserDTO.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/UserDTO.java index fbe9a0b..eef5679 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/UserDTO.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/dto/user/UserDTO.java @@ -1,6 +1,7 @@ package ru.nsu.fit.wheretogo.dto.user; import lombok.Getter; +import lombok.Setter; import ru.nsu.fit.wheretogo.dto.BaseDTO; import ru.nsu.fit.wheretogo.entity.user.User; @@ -9,6 +10,7 @@ import java.time.Instant; @Getter +@Setter public class UserDTO extends BaseDTO { @NotNull @@ -33,16 +35,4 @@ public static UserDTO getFromEntity(User user) { return dto; } - - public void setEmail(String email) { - this.email = email; - } - - public void setUsername(String username) { - this.username = username; - } - - public void setCreatedAt(Instant createdAt) { - this.createdAt = createdAt; - } } diff --git a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/entity/place/Place.java b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/entity/place/Place.java index b0292e4..e10a64e 100644 --- a/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/entity/place/Place.java +++ b/where-to-go-back/src/main/java/ru/nsu/fit/wheretogo/entity/place/Place.java @@ -56,6 +56,9 @@ public class Place { @Column(name = "UPLOADED_AT", nullable = false) private Instant uploadedAt; + @Column(name = "DURATION", nullable = false) + private Integer duration; + @PrePersist public void setUploadDate() { diff --git a/where-to-go-back/src/main/resources/db/migration/V16__Add_Time_Duration_To_Places.sql b/where-to-go-back/src/main/resources/db/migration/V16__Add_Time_Duration_To_Places.sql new file mode 100644 index 0000000..a250f5b --- /dev/null +++ b/where-to-go-back/src/main/resources/db/migration/V16__Add_Time_Duration_To_Places.sql @@ -0,0 +1,4 @@ +ALTER TABLE IF EXISTS T_PLACE ADD COLUMN DURATION INT NOT NULL DEFAULT 90; + +CREATE INDEX IF NOT EXISTS LATITUDE_INDEX ON T_PLACE USING BTREE(LATITUDE); +CREATE INDEX IF NOT EXISTS LONGITUDE_INDEX ON T_PLACE USING BTREE(LONGITUDE); diff --git a/where-to-go-back/src/main/resources/db/migration/V17__Add_Places_Durations.sql b/where-to-go-back/src/main/resources/db/migration/V17__Add_Places_Durations.sql new file mode 100644 index 0000000..c12f3f3 --- /dev/null +++ b/where-to-go-back/src/main/resources/db/migration/V17__Add_Places_Durations.sql @@ -0,0 +1,123 @@ +CREATE OR REPLACE FUNCTION RANDOM_BETWEEN(LOW INT, HIGH INT) + RETURNS INT AS +$$ +BEGIN + RETURN FLOOR(RANDOM() * (HIGH - LOW + 1) + LOW); +END; +$$ LANGUAGE PLPGSQL STRICT; + +CREATE OR REPLACE FUNCTION CREATE_RANDOM_DURATION() + RETURNS INT AS +$$ +BEGIN + RETURN RANDOM_BETWEEN(45, 180); +END; +$$ LANGUAGE PLPGSQL STRICT; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Заброшенный корабль'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Беловский водопад'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Мира парк'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Новое яркое пятно в городе'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Реконструкция старого города'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Феликс дзержинский'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Страшно красивое место'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Валадилена'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Тут всегда солнечно'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Банкет'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Архитектурное наслаждение'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Безграничность'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Безлюдный обрыв'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Белая соль'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Белена'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Брошенный остров'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Вечное зарево'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'В мире литературы'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'В окружении красок'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Геометрия'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Весенний контраст'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Второе самое красивое место'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Действующая психиатрическая больница'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Громадный шар посреди поля'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Единение с природой'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Восстановление'; + +UPDATE T_PLACE +SET DURATION = CREATE_RANDOM_DURATION() +WHERE NAME LIKE 'Масштабная забытость'; \ No newline at end of file diff --git a/where-to-go-back/src/main/resources/db/migration/V18__Update_Places_View.sql b/where-to-go-back/src/main/resources/db/migration/V18__Update_Places_View.sql new file mode 100644 index 0000000..af66dc8 --- /dev/null +++ b/where-to-go-back/src/main/resources/db/migration/V18__Update_Places_View.sql @@ -0,0 +1,9 @@ +DROP VIEW IF EXISTS V_PLACES_INFO; + +CREATE VIEW V_PLACES_INFO +AS +SELECT T_PLACE.*, CATEGORY_ID +FROM T_PLACE + JOIN T_PLACE_CATEGORY PC ON T_PLACE.ID = PC.PLACE_ID +ORDER BY T_PLACE.ID; +COMMENT ON VIEW V_PLACES_INFO IS 'Содержит полную информацию о местах, в том числе их категории и подкатегории'; \ No newline at end of file diff --git a/where-to-go-back/src/main/resources/db/migration/V19__Update_Place_Functions.sql b/where-to-go-back/src/main/resources/db/migration/V19__Update_Place_Functions.sql new file mode 100644 index 0000000..73e545e --- /dev/null +++ b/where-to-go-back/src/main/resources/db/migration/V19__Update_Place_Functions.sql @@ -0,0 +1,647 @@ +DROP FUNCTION IF EXISTS FILTER_CANDIDATES_BY_CATEGORY_IDS; +CREATE OR REPLACE FUNCTION FILTER_CANDIDATES_BY_CATEGORY_IDS( + MY_LAT DOUBLE PRECISION, + MY_LON DOUBLE PRECISION, + DLAT DOUBLE PRECISION, + DLON DOUBLE PRECISION, + _IDS INT[], + _LIMIT INT, + _MAX_DIST DOUBLE PRECISION, + DEG2DIST DOUBLE PRECISION) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION VARCHAR(255), + NAME VARCHAR(255), + THUMBNAIL VARCHAR(255), + UPLOADED_AT TIMESTAMP, + DURATION INTEGER, + DIST DOUBLE PRECISION + ) + LANGUAGE PLPGSQL +AS +$$ +BEGIN + RETURN QUERY (WITH CTE1 + AS (SELECT V_PLACES_INFO.ID, + V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE, + V_PLACES_INFO.DESCRIPTION, + V_PLACES_INFO.NAME, + V_PLACES_INFO.THUMBNAIL, + V_PLACES_INFO.UPLOADED_AT, + V_PLACES_INFO.CATEGORY_ID, + V_PLACES_INFO.DURATION, + @DEG2DIST * GCDIST(@MY_LAT, @MY_LON, V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE) AS DIST + FROM V_PLACES_INFO + WHERE V_PLACES_INFO.LATITUDE BETWEEN @MY_LAT - @DLAT + AND @MY_LAT + @DLAT + AND V_PLACES_INFO.LONGITUDE BETWEEN @MY_LON - @DLON + AND @MY_LON + @DLON + AND V_PLACES_INFO.CATEGORY_ID = ANY (_IDS) + AND @DEG2DIST * GCDIST(@MY_LAT, @MY_LON, V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE) <= _MAX_DIST + ORDER BY DIST, V_PLACES_INFO.ID) + SELECT DISTINCT CTE1.ID, + CTE1.LATITUDE, + CTE1.LONGITUDE, + CTE1.DESCRIPTION, + CTE1.NAME, + CTE1.THUMBNAIL, + CTE1.UPLOADED_AT, + CTE1.DURATION, + CTE1.DIST + FROM CTE1 + ORDER BY CTE1.DIST + LIMIT _LIMIT); +END; +$$; + +COMMENT ON FUNCTION FILTER_CANDIDATES_BY_CATEGORY_IDS( + MY_LAT DOUBLE PRECISION, + MY_LON DOUBLE PRECISION, + DLAT DOUBLE PRECISION, + DLON DOUBLE PRECISION, + _IDS INT[], + _LIMIT INT, + _MAX_DIST DOUBLE PRECISION, + DEG2DIST DOUBLE PRECISION) + IS 'Функция фильтрации множества найденных кандидатов с учетом категорий'; + + +--Функция фильтрации множества найденных кандидатов с учетом посещенных мест +DROP FUNCTION IF EXISTS FILTER_CANDIDATES_BY_VISITED_IDS; +CREATE OR REPLACE FUNCTION FILTER_CANDIDATES_BY_VISITED_IDS( + MY_LAT DOUBLE PRECISION, + MY_LON DOUBLE PRECISION, + DLAT DOUBLE PRECISION, + DLON DOUBLE PRECISION, + _IDS INT[], + _LIMIT INT, + _MAX_DIST DOUBLE PRECISION, + DEG2DIST DOUBLE PRECISION) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION VARCHAR(255), + NAME VARCHAR(255), + THUMBNAIL VARCHAR(255), + UPLOADED_AT TIMESTAMP, + DURATION INTEGER, + DIST DOUBLE PRECISION + ) + LANGUAGE PLPGSQL +AS +$$ +BEGIN + RETURN QUERY (WITH CTE1 + AS (SELECT V_PLACES_INFO.ID, + V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE, + V_PLACES_INFO.DESCRIPTION, + V_PLACES_INFO.NAME, + V_PLACES_INFO.THUMBNAIL, + V_PLACES_INFO.UPLOADED_AT, + V_PLACES_INFO.CATEGORY_ID, + V_PLACES_INFO.DURATION, + @DEG2DIST * GCDIST(@MY_LAT, @MY_LON, V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE) AS DIST + FROM V_PLACES_INFO + WHERE V_PLACES_INFO.LATITUDE BETWEEN @MY_LAT - @DLAT + AND @MY_LAT + @DLAT + AND V_PLACES_INFO.LONGITUDE BETWEEN @MY_LON - @DLON + AND @MY_LON + @DLON + AND V_PLACES_INFO.ID != ANY (_IDS) + AND @DEG2DIST * GCDIST(@MY_LAT, @MY_LON, V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE) <= _MAX_DIST + ORDER BY DIST, V_PLACES_INFO.ID) + SELECT DISTINCT CTE1.ID, + CTE1.LATITUDE, + CTE1.LONGITUDE, + CTE1.DESCRIPTION, + CTE1.NAME, + CTE1.THUMBNAIL, + CTE1.UPLOADED_AT, + CTE1.DURATION, + CTE1.DIST + FROM CTE1 + ORDER BY CTE1.DIST + LIMIT _LIMIT); +END; +$$; + +COMMENT ON FUNCTION FILTER_CANDIDATES_BY_VISITED_IDS( + MY_LAT DOUBLE PRECISION, + MY_LON DOUBLE PRECISION, + DLAT DOUBLE PRECISION, + DLON DOUBLE PRECISION, + _IDS INT[], + _LIMIT INT, + _MAX_DIST DOUBLE PRECISION, + DEG2DIST DOUBLE PRECISION) + IS 'Функция фильтрации множества найденных кандидатов с учетом посещенных мест'; + + +DROP FUNCTION IF EXISTS FIND_NEAREST_WITH_CATEGORY_IDS; +CREATE FUNCTION FIND_NEAREST_WITH_CATEGORY_IDS( + _MY_LAT DOUBLE PRECISION, + _MY_LON DOUBLE PRECISION, + _START_DIST DOUBLE PRECISION, + _MAX_DIST DOUBLE PRECISION, + _LIMIT INTEGER, + _IDS TEXT +) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION CHARACTER VARYING, + NAME CHARACTER VARYING, + THUMBNAIL CHARACTER VARYING, + UPLOADED_AT TIMESTAMP WITHOUT TIME ZONE, + DURATION INTEGER, + DIST DOUBLE PRECISION + ) + LANGUAGE PLPGSQL +AS +$$ +DECLARE + _DEG2RAD DOUBLE PRECISION DEFAULT PI() / 180; + MY_LAT DOUBLE PRECISION := _MY_LAT; + MY_LON DOUBLE PRECISION := _MY_LON; + DEG2DIST DOUBLE PRECISION := 69.172; /*69.172 for miles; 111.325 for km *** (mi vs km)*/ + START_DEG DOUBLE PRECISION := _START_DIST / @DEG2DIST; /*начальный радиус поиска*/ + MAX_DEG DOUBLE PRECISION := _MAX_DIST / @DEG2DIST; /*максимальный радиус поиска*/ + CUTOFF DOUBLE PRECISION := @MAX_DEG / SQRT(2); + DLAT DOUBLE PRECISION := @START_DEG; + DLON DOUBLE PRECISION; + LON2LAT DOUBLE PRECISION := COS(_DEG2RAD * @MY_LAT); + ITERATIONS INT := 0; + NEAR_CT INT; + WEST_LON DOUBLE PRECISION; + EAST_LON DOUBLE PRECISION; + IDS INT ARRAY; +BEGIN + IDS = STRING_TO_ARRAY(_IDS, ','); + + <> + LOOP + ITERATIONS := @ITERATIONS + 1; + DLON := ABS(@DLAT / @LON2LAT); + + IF ABS(@MY_LAT) + @DLAT >= 90 + THEN + DLON := 361; + ELSE + --nothing + END IF; + + NEAR_CT = FIND_NEAR_CT(MY_LAT := MY_LAT, MY_LON := MY_LON, DLAT := DLAT, DLON := DLON); + + IF (@NEAR_CT >= _LIMIT OR + @DLAT >= @CUTOFF) THEN + EXIT MAINLOOP;/*Выход из цикла*/ + END IF; + /*Расширяем квадрат поиска*/ + DLAT := LEAST(2 * @DLAT, @CUTOFF);/*Удваиваем радиус поиска*/ + END LOOP + MAINLOOP; + + + /*Мы вышли из цикла, если нашли достаточно мест, либо вышли за пределы граничных условий и сдались*/ + /*Теперь нужно получить информацию о найденных местах, если они есть*/ + /*Причем отобрать нужное количество, ибо мы могли найти больше*/ + + IF (@DLAT >= @MAX_DEG OR @DLON >= 180) + THEN + DLAT := @MAX_DEG; + ELSE + DLAT := GCDIST(ABS(@MY_LAT), @MY_LON, + ABS(@MY_LAT) - @DLAT, @MY_LON - @DLON); + END IF; + + DLON := COALESCE(ASIN(SIN(_DEG2RAD * @DLAT) / COS(_DEG2RAD * @MY_LAT)) / _DEG2RAD, 361); + + /*Последний запрос, который берет информацию об отобранных кандидатах*/ + /*Если мы не вышли в отрицательные координаты*/ + IF (ABS(@MY_LON) + @DLON < 180 OR + ABS(@MY_LAT) + @DLAT < 90) THEN + RETURN QUERY (SELECT * + FROM FILTER_CANDIDATES_BY_CATEGORY_IDS( + MY_LAT := MY_LAT, + MY_LON := MY_LON, + DLAT := DLAT, + DLON := DLON, + _IDS := IDS, + _LIMIT := _LIMIT, + _MAX_DIST := _MAX_DIST, + DEG2DIST := DEG2DIST)); + ELSE + /*Если вышли в отрицательные координаты, то пересчитываем*/ + CASE + WHEN @MY_LON < 0 + THEN WEST_LON := @MY_LON; + ELSE WEST_LON := @MY_LON - 360; + END CASE; + + EAST_LON := @WEST_LON + 360; + + RETURN QUERY (SELECT * + FROM FILTER_CANDIDATES_BY_CATEGORY_IDS( + MY_LAT := MY_LAT, + MY_LON := WEST_LON, + DLAT := DLAT, + DLON := DLON, + _IDS := IDS, + _LIMIT := _LIMIT, + _MAX_DIST := _MAX_DIST, + DEG2DIST := DEG2DIST)); + END IF; +END; +$$; + +COMMENT ON FUNCTION FIND_NEAREST_WITH_CATEGORY_IDS( + _MY_LAT DOUBLE PRECISION, + _MY_LON DOUBLE PRECISION, + _START_DIST DOUBLE PRECISION, + _MAX_DIST DOUBLE PRECISION, + _LIMIT INTEGER, + _IDS TEXT) + IS 'Основная функция поиска набора мест вблизи заданной геоточки с учетом категорий'; + + +DROP FUNCTION IF EXISTS FIND_NEAREST_WITH_VISITED_IDS; +CREATE FUNCTION FIND_NEAREST_WITH_VISITED_IDS( + _MY_LAT DOUBLE PRECISION, + _MY_LON DOUBLE PRECISION, + _START_DIST DOUBLE PRECISION, + _MAX_DIST DOUBLE PRECISION, + _LIMIT INTEGER, + _IDS TEXT +) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION CHARACTER VARYING, + NAME CHARACTER VARYING, + THUMBNAIL CHARACTER VARYING, + UPLOADED_AT TIMESTAMP WITHOUT TIME ZONE, + DURATION INTEGER, + DIST DOUBLE PRECISION + ) + LANGUAGE PLPGSQL +AS +$$ +DECLARE + _DEG2RAD DOUBLE PRECISION DEFAULT PI() / 180; + MY_LAT DOUBLE PRECISION := _MY_LAT; + MY_LON DOUBLE PRECISION := _MY_LON; + DEG2DIST DOUBLE PRECISION := 69.172; /*69.172 for miles; 111.325 for km *** (mi vs km)*/ + START_DEG DOUBLE PRECISION := _START_DIST / @DEG2DIST; /*начальный радиус поиска*/ + MAX_DEG DOUBLE PRECISION := _MAX_DIST / @DEG2DIST; /*максимальный радиус поиска*/ + CUTOFF DOUBLE PRECISION := @MAX_DEG / SQRT(2); + DLAT DOUBLE PRECISION := @START_DEG; + DLON DOUBLE PRECISION; + LON2LAT DOUBLE PRECISION := COS(_DEG2RAD * @MY_LAT); + ITERATIONS INT := 0; + NEAR_CT INT; + WEST_LON DOUBLE PRECISION; + EAST_LON DOUBLE PRECISION; + IDS INT ARRAY; +BEGIN + IDS = STRING_TO_ARRAY(_IDS, ','); + + <> + LOOP + ITERATIONS := @ITERATIONS + 1; + DLON := ABS(@DLAT / @LON2LAT); + + IF ABS(@MY_LAT) + @DLAT >= 90 + THEN + DLON := 361; + ELSE + --nothing + END IF; + + NEAR_CT = FIND_NEAR_CT(MY_LAT := MY_LAT, MY_LON := MY_LON, DLAT := DLAT, DLON := DLON); + + IF (@NEAR_CT >= _LIMIT OR + @DLAT >= @CUTOFF) THEN + EXIT MAINLOOP;/*Выход из цикла*/ + END IF; + /*Расширяем квадрат поиска*/ + DLAT := LEAST(2 * @DLAT, @CUTOFF);/*Удваиваем радиус поиска*/ + END LOOP + MAINLOOP; + + + /*Мы вышли из цикла, если нашли достаточно мест, либо вышли за пределы граничных условий и сдались*/ + /*Теперь нужно получить информацию о найденных местах, если они есть*/ + /*Причем отобрать нужное количетсво, ибо мы могли найти больше*/ + + IF (@DLAT >= @MAX_DEG OR @DLON >= 180) + THEN + DLAT := @MAX_DEG; + ELSE + DLAT := GCDIST(ABS(@MY_LAT), @MY_LON, + ABS(@MY_LAT) - @DLAT, @MY_LON - @DLON); + END IF; + + DLON := COALESCE(ASIN(SIN(_DEG2RAD * @DLAT) / COS(_DEG2RAD * @MY_LAT)) / _DEG2RAD, 361); + + /*Последний запрос, который берет информацию об отобранных кандидатах*/ + /*Если мы не вышли в отрицательные координаты*/ + IF (ABS(@MY_LON) + @DLON < 180 OR + ABS(@MY_LAT) + @DLAT < 90) THEN + RETURN QUERY (SELECT * + FROM FILTER_CANDIDATES_BY_VISITED_IDS( + MY_LAT := MY_LAT, + MY_LON := MY_LON, + DLAT := DLAT, + DLON := DLON, + _IDS := IDS, + _LIMIT := _LIMIT, + _MAX_DIST := _MAX_DIST, + DEG2DIST := DEG2DIST)); + ELSE + /*Если вышли в отрицательные координаты, то пересчитываем*/ + CASE + WHEN @MY_LON < 0 + THEN WEST_LON := @MY_LON; + ELSE WEST_LON := @MY_LON - 360; + END CASE; + + EAST_LON := @WEST_LON + 360; + + RETURN QUERY (SELECT * + FROM FILTER_CANDIDATES_BY_VISITED_IDS( + MY_LAT := MY_LAT, + MY_LON := WEST_LON, + DLAT := DLAT, + DLON := DLON, + _IDS := IDS, + _LIMIT := _LIMIT, + _MAX_DIST := _MAX_DIST, + DEG2DIST := DEG2DIST)); + END IF; +END; +$$; + +COMMENT ON FUNCTION FIND_NEAREST_WITH_VISITED_IDS( + _MY_LAT DOUBLE PRECISION, + _MY_LON DOUBLE PRECISION, + _START_DIST DOUBLE PRECISION, + _MAX_DIST DOUBLE PRECISION, + _LIMIT INTEGER, + _IDS TEXT) + IS 'Основная функция поиска набора мест вблизи заданной геоточки с учетом посещенных мест'; + + +DROP FUNCTION IF EXISTS GET_PLACES; +CREATE FUNCTION GET_PLACES(_IDS TEXT) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION CHARACTER VARYING, + NAME CHARACTER VARYING, + THUMBNAIL CHARACTER VARYING, + UPLOADED_AT TIMESTAMP WITHOUT TIME ZONE, + DURATION INTEGER + ) + LANGUAGE PLPGSQL +AS +$$ +DECLARE + IDS INT ARRAY; +BEGIN + IDS = STRING_TO_ARRAY(_IDS, ','); + RETURN QUERY (WITH CTE1 AS (SELECT V_PLACES_INFO.ID, + V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE, + V_PLACES_INFO.DESCRIPTION, + V_PLACES_INFO.NAME, + V_PLACES_INFO.THUMBNAIL, + V_PLACES_INFO.UPLOADED_AT, + V_PLACES_INFO.CATEGORY_ID, + V_PLACES_INFO.DURATION + FROM V_PLACES_INFO + WHERE V_PLACES_INFO.CATEGORY_ID = ANY (IDS) + ORDER BY V_PLACES_INFO.NAME) + SELECT DISTINCT CTE1.ID, + CTE1.LATITUDE, + CTE1.LONGITUDE, + CTE1.DESCRIPTION, + CTE1.NAME, + CTE1.THUMBNAIL, + CTE1.UPLOADED_AT, + CTE1.DURATION + FROM CTE1); +END +$$; + +COMMENT ON FUNCTION GET_PLACES(_IDS TEXT) IS 'Функция получения всех мест из БД в соответствии с категориями'; + + +--Упрощенные функции без индексов +DROP FUNCTION IF EXISTS FILTER_CANDIDATES; +CREATE OR REPLACE FUNCTION FILTER_CANDIDATES( + MY_LAT DOUBLE PRECISION, + MY_LON DOUBLE PRECISION, + DLAT DOUBLE PRECISION, + DLON DOUBLE PRECISION, + _LIMIT INT, + _MAX_DIST DOUBLE PRECISION, + DEG2DIST DOUBLE PRECISION) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION VARCHAR(255), + NAME VARCHAR(255), + THUMBNAIL VARCHAR(255), + UPLOADED_AT TIMESTAMP, + DURATION INTEGER, + DIST DOUBLE PRECISION + ) + LANGUAGE PLPGSQL +AS +$$ +BEGIN + RETURN QUERY (WITH CTE1 + AS (SELECT V_PLACES_INFO.ID, + V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE, + V_PLACES_INFO.DESCRIPTION, + V_PLACES_INFO.NAME, + V_PLACES_INFO.THUMBNAIL, + V_PLACES_INFO.UPLOADED_AT, + V_PLACES_INFO.CATEGORY_ID, + V_PLACES_INFO.DURATION, + @DEG2DIST * GCDIST(@MY_LAT, @MY_LON, V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE) AS DIST + FROM V_PLACES_INFO + WHERE V_PLACES_INFO.LATITUDE BETWEEN @MY_LAT - @DLAT + AND @MY_LAT + @DLAT + AND V_PLACES_INFO.LONGITUDE BETWEEN @MY_LON - @DLON + AND @MY_LON + @DLON + AND @DEG2DIST * GCDIST(@MY_LAT, @MY_LON, V_PLACES_INFO.LATITUDE, + V_PLACES_INFO.LONGITUDE) <= _MAX_DIST + ORDER BY DIST, V_PLACES_INFO.ID) + SELECT DISTINCT CTE1.ID, + CTE1.LATITUDE, + CTE1.LONGITUDE, + CTE1.DESCRIPTION, + CTE1.NAME, + CTE1.THUMBNAIL, + CTE1.UPLOADED_AT, + CTE1.DURATION, + CTE1.DIST + FROM CTE1 + ORDER BY CTE1.DIST + LIMIT _LIMIT); +END; +$$; + +COMMENT ON FUNCTION FILTER_CANDIDATES( + MY_LAT DOUBLE PRECISION, + MY_LON DOUBLE PRECISION, + DLAT DOUBLE PRECISION, + DLON DOUBLE PRECISION, + _LIMIT INT, + _MAX_DIST DOUBLE PRECISION, + DEG2DIST DOUBLE PRECISION) + IS 'Функция фильтрации множества найденных кандидатов'; + +DROP FUNCTION IF EXISTS FIND_NEAREST; +CREATE FUNCTION FIND_NEAREST( + _MY_LAT DOUBLE PRECISION, /*Широта в пределах [-90...90]*/ + _MY_LON DOUBLE PRECISION, /*Долгота в пределах [-180...180]*/ + _START_DIST DOUBLE PRECISION, /*Начальная оценка расстояния поиска*/ + _MAX_DIST DOUBLE PRECISION, /*Максимальная дистанция где искать*/ + _LIMIT INT /*Сколько найденных кандидатов нужно (делать сильно большим не стоит, чтобы не нагружать карту)*/ +) + RETURNS TABLE + ( + ID BIGINT, + LATITUDE NUMERIC, + LONGITUDE NUMERIC, + DESCRIPTION VARCHAR(255), + NAME VARCHAR(255), + THUMBNAIL VARCHAR(255), + UPLOADED_AT TIMESTAMP, + DURATION INTEGER, + DIST DOUBLE PRECISION + ) +AS +$$ +DECLARE + _DEG2RAD DOUBLE PRECISION DEFAULT PI() / 180; + MY_LAT DOUBLE PRECISION := _MY_LAT; + MY_LON DOUBLE PRECISION := _MY_LON; + DEG2DIST DOUBLE PRECISION := 69.172; /*69.172 for miles; 111.325 for km *** (mi vs km)*/ + START_DEG DOUBLE PRECISION := _START_DIST / @DEG2DIST; /*начальный радиус поиска*/ + MAX_DEG DOUBLE PRECISION := _MAX_DIST / @DEG2DIST; /*максимальный радиус поиска*/ + CUTOFF DOUBLE PRECISION := @MAX_DEG / SQRT(2); + DLAT DOUBLE PRECISION := @START_DEG; + DLON DOUBLE PRECISION; + LON2LAT DOUBLE PRECISION := COS(_DEG2RAD * @MY_LAT); + ITERATIONS INT := 0; + NEAR_CT INT; + WEST_LON DOUBLE PRECISION; + EAST_LON DOUBLE PRECISION; + +BEGIN + + <> + LOOP + ITERATIONS := @ITERATIONS + 1; + DLON := ABS(@DLAT / @LON2LAT); + + IF ABS(@MY_LAT) + @DLAT >= 90 + THEN + DLON := 361; + ELSE + --nothing + END IF; + + NEAR_CT = FIND_NEAR_CT(MY_LAT := MY_LAT, MY_LON := MY_LON, DLAT := DLAT, DLON := DLON); + + IF (@NEAR_CT >= _LIMIT OR + @DLAT >= @CUTOFF) THEN + EXIT MAINLOOP;/*Выход из цикла*/ + END IF; + /*Расширяем квадрат поиска*/ + DLAT := LEAST(2 * @DLAT, @CUTOFF);/*Удваиваем радиус поиска*/ + END LOOP + MAINLOOP; + + + /*Мы вышли из цикла, если нашли достаточно мест, либо вышли за пределы граничных условий и сдались*/ + /*Теперь нужно получить информацию о найденных местах, если они есть*/ + /*Причем отобрать нужное количество, ибо мы могли найти больше*/ + + IF (@DLAT >= @MAX_DEG OR @DLON >= 180) + THEN + DLAT := @MAX_DEG; + ELSE + DLAT := GCDIST(ABS(@MY_LAT), @MY_LON, + ABS(@MY_LAT) - @DLAT, @MY_LON - @DLON); + END IF; + + DLON := COALESCE(ASIN(SIN(_DEG2RAD * @DLAT) / COS(_DEG2RAD * @MY_LAT)) / _DEG2RAD, 361); + + /*Последний запрос, который берет информацию об отобранных кандидатах*/ + /*Если мы не вышли в отрицательные координаты*/ + IF (ABS(@MY_LON) + @DLON < 180 OR + ABS(@MY_LAT) + @DLAT < 90) THEN + RETURN QUERY (SELECT * + FROM FILTER_CANDIDATES( + MY_LAT := MY_LAT, + MY_LON := MY_LON, + DLAT := DLAT, + DLON := DLON, + _LIMIT := _LIMIT, + _MAX_DIST := _MAX_DIST, + DEG2DIST := DEG2DIST)); + ELSE + /*Если вышли в отрицательные координаты, то пересчитываем*/ + CASE + WHEN @MY_LON < 0 + THEN WEST_LON := @MY_LON; + ELSE WEST_LON := @MY_LON - 360; + END CASE; + + EAST_LON := @WEST_LON + 360; + + RETURN QUERY (SELECT * + FROM FILTER_CANDIDATES( + MY_LAT := MY_LAT, + MY_LON := WEST_LON, + DLAT := DLAT, + DLON := DLON, + _LIMIT := _LIMIT, + _MAX_DIST := _MAX_DIST, + DEG2DIST := DEG2DIST)); + END IF; +END; +$$ LANGUAGE PLPGSQL; + +COMMENT ON FUNCTION FIND_NEAREST( + _MY_LAT DOUBLE PRECISION, + _MY_LON DOUBLE PRECISION, + _START_DIST DOUBLE PRECISION, + _MAX_DIST DOUBLE PRECISION, + _LIMIT INT + ) + IS 'Основная функция поиска ближайших мест к геоточке' \ No newline at end of file diff --git a/where-to-go-ui/app/build.gradle b/where-to-go-ui/app/build.gradle index cafa7a0..515c076 100644 --- a/where-to-go-ui/app/build.gradle +++ b/where-to-go-ui/app/build.gradle @@ -58,10 +58,11 @@ dependencies { implementation 'com.google.android.gms:play-services-maps:18.1.0' implementation 'com.google.android.libraries.places:places:3.2.0' implementation 'androidx.slidingpanelayout:slidingpanelayout:1.2.0' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' implementation 'com.google.maps.android:android-maps-utils:2.3.0' implementation 'com.github.bumptech.glide:glide:4.12.0' implementation "android.arch.work:work-runtime:1.0.1" + + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' } \ No newline at end of file diff --git a/where-to-go-ui/app/src/main/java/ru/nsu/fit/wheretogo/model/entity/Place.java b/where-to-go-ui/app/src/main/java/ru/nsu/fit/wheretogo/model/entity/Place.java index d261ef5..2428f8e 100644 --- a/where-to-go-ui/app/src/main/java/ru/nsu/fit/wheretogo/model/entity/Place.java +++ b/where-to-go-ui/app/src/main/java/ru/nsu/fit/wheretogo/model/entity/Place.java @@ -7,7 +7,6 @@ import java.util.List; - public class Place { @SerializedName("id") @@ -28,6 +27,9 @@ public class Place { @SerializedName("uploadedAt") @Expose private String uploadedAt; + @SerializedName("duration") + @Expose + private Integer duration; @SerializedName("categories") @Expose private List categories; @@ -116,6 +118,14 @@ public void setLongitude(Double longitude) { this.coordinates.setLatitude(longitude); } + public Integer getDuration() { + return duration; + } + + public void setDuration(Integer duration) { + this.duration = duration; + } + @NonNull @Override public String toString() { diff --git a/where-to-go-ui/app/src/main/res/drawable-v24/make_path_btn.png b/where-to-go-ui/app/src/main/res/drawable-v24/make_path_btn.png new file mode 100644 index 0000000000000000000000000000000000000000..11781945a1edccbf900efb56ce2d6bd819ed5618 GIT binary patch literal 1715 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 u4(7Ax@|`D6OsCC<9=hxh{QvQPd;Aa0* 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 Hu0mjfo45sJ literal 7377 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 - - + - + - + - + - + - + - + - + - - \ No newline at end of file + + + + + + + + + + + + \ No newline at end of file diff --git a/where-to-go-ui/build.gradle b/where-to-go-ui/build.gradle index b8575ba..d14204e 100644 --- a/where-to-go-ui/build.gradle +++ b/where-to-go-ui/build.gradle @@ -5,11 +5,11 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.0.2' + classpath 'com.android.tools.build:gradle:8.1.2' classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.2.0" } } -task clean(type: Delete) { +tasks.register('clean', Delete) { delete rootProject.buildDir } \ No newline at end of file