@@ -117,6 +117,116 @@ public CompletableFuture<Response> searchPhotos(
117117 }
118118 }
119119
120+ @ GET
121+ @ Path ("/{userId}/immich/photos/map-markers" )
122+ @ RolesAllowed ({"USER" , "ADMIN" })
123+ @ Blocking
124+ public CompletableFuture <Response > getPhotoMapMarkers (
125+ @ PathParam ("userId" ) String userIdStr ,
126+ @ QueryParam ("startDate" ) String startDateStr ,
127+ @ QueryParam ("endDate" ) String endDateStr ,
128+ @ QueryParam ("latitude" ) Double latitude ,
129+ @ QueryParam ("longitude" ) Double longitude ,
130+ @ QueryParam ("radiusMeters" ) Double radiusMeters ,
131+ @ QueryParam ("city" ) String city ,
132+ @ QueryParam ("country" ) String country ,
133+ @ QueryParam ("coordinatePrecision" ) Integer coordinatePrecision ) {
134+
135+ UUID userId = parseUserId (userIdStr );
136+ validateUserAccess (userId );
137+
138+ try {
139+ ImmichPhotoSearchRequest searchRequest = new ImmichPhotoSearchRequest ();
140+ searchRequest .setStartDate (OffsetDateTime .parse (startDateStr ));
141+ searchRequest .setEndDate (OffsetDateTime .parse (endDateStr ));
142+ searchRequest .setLatitude (latitude );
143+ searchRequest .setLongitude (longitude );
144+ searchRequest .setRadiusMeters (radiusMeters );
145+ searchRequest .setCity (city );
146+ searchRequest .setCountry (country );
147+
148+ return immichService .getPhotoMapMarkers (userId , searchRequest , coordinatePrecision )
149+ .thenApply (result -> Response .ok (ApiResponse .success (result )).build ())
150+ .exceptionally (throwable -> {
151+ log .error ("Failed to get map markers for user {}: {}" , userId , throwable .getMessage (), throwable );
152+ return Response .status (Response .Status .INTERNAL_SERVER_ERROR )
153+ .entity (ApiResponse .error ("Failed to get map markers" ))
154+ .build ();
155+ });
156+ } catch (Exception e ) {
157+ log .error ("Invalid map marker parameters for user {}: {}" , userId , e .getMessage ());
158+ return CompletableFuture .completedFuture (
159+ Response .status (Response .Status .BAD_REQUEST )
160+ .entity (ApiResponse .error ("Invalid map marker parameters: " + e .getMessage ()))
161+ .build ()
162+ );
163+ }
164+ }
165+
166+ @ GET
167+ @ Path ("/{userId}/immich/photos/map-marker/photos" )
168+ @ RolesAllowed ({"USER" , "ADMIN" })
169+ @ Blocking
170+ public CompletableFuture <Response > getPhotosForMapMarker (
171+ @ PathParam ("userId" ) String userIdStr ,
172+ @ QueryParam ("startDate" ) String startDateStr ,
173+ @ QueryParam ("endDate" ) String endDateStr ,
174+ @ QueryParam ("latitude" ) Double latitude ,
175+ @ QueryParam ("longitude" ) Double longitude ,
176+ @ QueryParam ("radiusMeters" ) Double radiusMeters ,
177+ @ QueryParam ("city" ) String city ,
178+ @ QueryParam ("country" ) String country ,
179+ @ QueryParam ("markerLatitude" ) Double markerLatitude ,
180+ @ QueryParam ("markerLongitude" ) Double markerLongitude ,
181+ @ QueryParam ("coordinatePrecision" ) Integer coordinatePrecision ,
182+ @ QueryParam ("limit" ) Integer limit ) {
183+
184+ UUID userId = parseUserId (userIdStr );
185+ validateUserAccess (userId );
186+
187+ if (markerLatitude == null || markerLongitude == null ) {
188+ return CompletableFuture .completedFuture (
189+ Response .status (Response .Status .BAD_REQUEST )
190+ .entity (ApiResponse .error ("markerLatitude and markerLongitude are required" ))
191+ .build ()
192+ );
193+ }
194+
195+ try {
196+ ImmichPhotoSearchRequest searchRequest = new ImmichPhotoSearchRequest ();
197+ searchRequest .setStartDate (OffsetDateTime .parse (startDateStr ));
198+ searchRequest .setEndDate (OffsetDateTime .parse (endDateStr ));
199+ searchRequest .setLatitude (latitude );
200+ searchRequest .setLongitude (longitude );
201+ searchRequest .setRadiusMeters (radiusMeters );
202+ searchRequest .setCity (city );
203+ searchRequest .setCountry (country );
204+
205+ return immichService .getPhotosForMapMarker (
206+ userId ,
207+ searchRequest ,
208+ markerLatitude ,
209+ markerLongitude ,
210+ coordinatePrecision ,
211+ limit
212+ )
213+ .thenApply (result -> Response .ok (ApiResponse .success (result )).build ())
214+ .exceptionally (throwable -> {
215+ log .error ("Failed to get marker photos for user {}: {}" , userId , throwable .getMessage (), throwable );
216+ return Response .status (Response .Status .INTERNAL_SERVER_ERROR )
217+ .entity (ApiResponse .error ("Failed to get marker photos" ))
218+ .build ();
219+ });
220+ } catch (Exception e ) {
221+ log .error ("Invalid marker photo parameters for user {}: {}" , userId , e .getMessage ());
222+ return CompletableFuture .completedFuture (
223+ Response .status (Response .Status .BAD_REQUEST )
224+ .entity (ApiResponse .error ("Invalid marker photo parameters: " + e .getMessage ()))
225+ .build ()
226+ );
227+ }
228+ }
229+
120230 @ GET
121231 @ Path ("/{userId}/immich/photos/{photoId}/thumbnail" )
122232 @ Produces ("image/jpeg" )
@@ -231,6 +341,58 @@ public CompletableFuture<Response> searchCurrentUserPhotos(
231341 return searchPhotos (userId .toString (), startDateStr , endDateStr , latitude , longitude , radiusMeters , city , country , limit );
232342 }
233343
344+ @ GET
345+ @ Path ("/me/immich/photos/map-markers" )
346+ @ RolesAllowed ({"USER" , "ADMIN" })
347+ @ Blocking
348+ public CompletableFuture <Response > getCurrentUserPhotoMapMarkers (
349+ @ QueryParam ("startDate" ) String startDateStr ,
350+ @ QueryParam ("endDate" ) String endDateStr ,
351+ @ QueryParam ("latitude" ) Double latitude ,
352+ @ QueryParam ("longitude" ) Double longitude ,
353+ @ QueryParam ("radiusMeters" ) Double radiusMeters ,
354+ @ QueryParam ("city" ) String city ,
355+ @ QueryParam ("country" ) String country ,
356+ @ QueryParam ("coordinatePrecision" ) Integer coordinatePrecision ) {
357+
358+ UUID userId = currentUserService .getCurrentUserId ();
359+ return getPhotoMapMarkers (userId .toString (), startDateStr , endDateStr , latitude , longitude , radiusMeters , city , country , coordinatePrecision );
360+ }
361+
362+ @ GET
363+ @ Path ("/me/immich/photos/map-marker/photos" )
364+ @ RolesAllowed ({"USER" , "ADMIN" })
365+ @ Blocking
366+ public CompletableFuture <Response > getCurrentUserPhotosForMapMarker (
367+ @ QueryParam ("startDate" ) String startDateStr ,
368+ @ QueryParam ("endDate" ) String endDateStr ,
369+ @ QueryParam ("latitude" ) Double latitude ,
370+ @ QueryParam ("longitude" ) Double longitude ,
371+ @ QueryParam ("radiusMeters" ) Double radiusMeters ,
372+ @ QueryParam ("city" ) String city ,
373+ @ QueryParam ("country" ) String country ,
374+ @ QueryParam ("markerLatitude" ) Double markerLatitude ,
375+ @ QueryParam ("markerLongitude" ) Double markerLongitude ,
376+ @ QueryParam ("coordinatePrecision" ) Integer coordinatePrecision ,
377+ @ QueryParam ("limit" ) Integer limit ) {
378+
379+ UUID userId = currentUserService .getCurrentUserId ();
380+ return getPhotosForMapMarker (
381+ userId .toString (),
382+ startDateStr ,
383+ endDateStr ,
384+ latitude ,
385+ longitude ,
386+ radiusMeters ,
387+ city ,
388+ country ,
389+ markerLatitude ,
390+ markerLongitude ,
391+ coordinatePrecision ,
392+ limit
393+ );
394+ }
395+
234396 @ GET
235397 @ Path ("/me/immich/photos/{photoId}/thumbnail" )
236398 @ Produces (MediaType .APPLICATION_OCTET_STREAM )
0 commit comments