Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix: 지도 기반 마커 조회 API 요청 시 NPE 오류 해결 #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
chanrhan merged 5 commits into develop from fix/44-photos-markers-npe-error
Nov 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import kr.kro.photoliner.domain.album.dto.request.AlbumDeleteRequest;
import kr.kro.photoliner.domain.album.dto.request.AlbumItemCreateRequest;
import kr.kro.photoliner.domain.album.dto.request.AlbumItemDeleteRequest;
import kr.kro.photoliner.domain.album.dto.request.AlbumPhotoMarkersRequest;
import kr.kro.photoliner.domain.album.dto.request.AlbumTitleUpdateRequest;
import kr.kro.photoliner.domain.album.dto.response.AlbumCreateResponse;
import kr.kro.photoliner.domain.album.dto.response.AlbumPhotoItemsResponse;
import kr.kro.photoliner.domain.album.dto.response.AlbumPhotoMarkersResponse;
import kr.kro.photoliner.domain.album.dto.response.AlbumsResponse;
import kr.kro.photoliner.domain.album.service.AlbumService;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -69,7 +71,7 @@ public ResponseEntity<Void> deletePhoto(
@GetMapping("/{albumId}/photos")
public ResponseEntity<AlbumPhotoItemsResponse> getAlbumItems(
@PathVariable Long albumId,
@PageableDefault(sort = "capturedDt", direction = Sort.Direction.DESC) Pageable pageable
@PageableDefault Pageable pageable
) {
return ResponseEntity.ok(albumService.getAlbumPhotoItems(albumId, pageable));
}
Expand All @@ -91,4 +93,12 @@ public ResponseEntity<Void> deleteAlbumItems(
albumService.deleteAlbumItems(albumId, request);
return ResponseEntity.noContent().build();
}

@GetMapping("/{albumId}/markers")
public ResponseEntity<AlbumPhotoMarkersResponse> getAlbumPhotoMarkers(
@PathVariable Long albumId,
@Valid AlbumPhotoMarkersRequest request
) {
return ResponseEntity.ok(albumService.getAlbumPhotoMarkers(albumId, request));
}
}
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package kr.kro.photoliner.domain.album.dto;

import java.time.LocalDateTime;
import java.util.Objects;
import org.locationtech.jts.geom.Point;

public record AlbumPhotoItem(
Long id,
Long photoId,
String fileName,
String filePath,
String thumbnailPath,
LocalDateTime capturedDt,
Point location
) {

public Double getLatitude() {
if (Objects.isNull(location)) {
return null;
}
return location.getY();
}

public Double getLongitude() {
if (Objects.isNull(location)) {
return null;
}
return location.getX();
}
}
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kr.kro.photoliner.domain.album.dto;

import java.util.List;

public record AlbumPhotoItems(
List<AlbumPhotoItem> photoItems
) {

public int count() {
return photoItems.size();
}
}
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package kr.kro.photoliner.domain.album.dto.request;

import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import org.locationtech.jts.geom.Coordinate;

public record AlbumPhotoMarkersRequest(
@Min(0) @Max(90)
double swLat,

@Min(0) @Max(180)
double swLng,

@Min(0) @Max(90)
double neLat,

@Min(0) @Max(180)
double neLng
) {
public Coordinate getSouthWestCoordinate() {
return new Coordinate(swLng, swLat);
}

public Coordinate getNorthEastCoordinate() {
return new Coordinate(neLng, neLat);
}
}
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import java.time.LocalDateTime;
import java.util.List;
import kr.kro.photoliner.domain.album.model.view.AlbumPhotoView;
import kr.kro.photoliner.domain.album.dto.AlbumPhotoItem;
import org.springframework.data.domain.Page;

public record AlbumPhotoItemsResponse(
List<InnerAlbumPhotoItem> items
) {

public static AlbumPhotoItemsResponse from(Page<AlbumPhotoView> albumPhotoViews) {
public static AlbumPhotoItemsResponse from(Page<AlbumPhotoItem> albumPhotoViews) {
return new AlbumPhotoItemsResponse(
albumPhotoViews.stream()
.map(InnerAlbumPhotoItem::from)
Expand All @@ -26,14 +26,14 @@ public record InnerAlbumPhotoItem(
LocalDateTime capturedDt
) {

public static InnerAlbumPhotoItem from(AlbumPhotoView albumPhotoView) {
public static InnerAlbumPhotoItem from(AlbumPhotoItem albumPhotoItem) {
return new InnerAlbumPhotoItem(
albumPhotoView.getId(),
albumPhotoView.getPhotoId(),
albumPhotoView.getFileName(),
albumPhotoView.getFilePath(),
albumPhotoView.getThumbnailPath(),
albumPhotoView.getCapturedDt()
albumPhotoItem.id(),
albumPhotoItem.photoId(),
albumPhotoItem.fileName(),
albumPhotoItem.filePath(),
albumPhotoItem.thumbnailPath(),
albumPhotoItem.capturedDt()
);
}
}
Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package kr.kro.photoliner.domain.album.dto.response;

import java.time.LocalDateTime;
import java.util.List;
import kr.kro.photoliner.domain.album.dto.AlbumPhotoItem;
import kr.kro.photoliner.domain.album.dto.AlbumPhotoItems;

public record AlbumPhotoMarkersResponse(
Integer count,
List<InnerAlbumPhotoMarker> albumPhotoMarkers
) {

public static AlbumPhotoMarkersResponse from(AlbumPhotoItems albumPhotoItems) {
return new AlbumPhotoMarkersResponse(
albumPhotoItems.count(),
albumPhotoItems.photoItems().stream()
.map(InnerAlbumPhotoMarker::from)
.toList()
);
}

public record InnerAlbumPhotoMarker(
Long id,
Long photoId,
String filePath,
String thumbnailPath,
LocalDateTime capturedDt,
Double lat,
Double lng
) {

public static InnerAlbumPhotoMarker from(AlbumPhotoItem albumPhotoItem) {
return new InnerAlbumPhotoMarker(
albumPhotoItem.id(),
albumPhotoItem.photoId(),
albumPhotoItem.filePath(),
albumPhotoItem.thumbnailPath(),
albumPhotoItem.capturedDt(),
albumPhotoItem.getLatitude(),
albumPhotoItem.getLongitude()
);
}
}
}
View file Open in desktop

This file was deleted.

View file Open in desktop

This file was deleted.

View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,30 +1,54 @@
package kr.kro.photoliner.domain.album.repository;

import java.util.List;
import kr.kro.photoliner.domain.album.model.view.AlbumPhotoView;
import kr.kro.photoliner.domain.album.model.view.AlbumPhotoViews;
import kr.kro.photoliner.domain.album.dto.AlbumPhotoItem;
import kr.kro.photoliner.domain.album.dto.AlbumPhotoItems;
import kr.kro.photoliner.domain.album.model.PhotoItem;
import org.locationtech.jts.geom.Point;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

public interface AlbumPhotoRepository extends JpaRepository<AlbumPhotoView, Long> {
Page<AlbumPhotoView> findByAlbumId(Long albumId, Pageable pageable);
public interface AlbumPhotoRepository extends JpaRepository<PhotoItem, Long> {
@Query("""
select new kr.kro.photoliner.domain.album.dto.AlbumPhotoItem(
pi.id,
pi.photoId,
p.fileName,
p.filePath,
p.thumbnailPath,
p.capturedDt,
p.location
)
from PhotoItem pi
inner join Photo p on p.id = pi.photoId
where pi.album.id = :albumId
""")
Page<AlbumPhotoItem> findByAlbumId(Long albumId, Pageable pageable);

@Query("""
select apv
from AlbumPhotoView apv
where apv.userId = :userId
and function('st_x', apv.location) between function('st_x', :sw) and function('st_x', :ne)
and function('st_y', apv.location) between function('st_y', :sw) and function('st_y', :ne)
order by apv.capturedDt desc
select new kr.kro.photoliner.domain.album.dto.AlbumPhotoItem(
pi.id,
pi.photoId,
p.fileName,
p.filePath,
p.thumbnailPath,
p.capturedDt,
p.location
)
from PhotoItem pi
inner join Photo p on p.id = pi.photoId
where pi.album.id = :albumId
and function('st_x', p.location) between function('st_x', :sw) and function('st_x', :ne)
and function('st_y', p.location) between function('st_y', :sw) and function('st_y', :ne)
order by p.capturedDt
""")
List<AlbumPhotoView> findByUserIdInBox(Long userId, Point sw, Point ne);
List<AlbumPhotoItem> findByAlbumIdInBox(Long albumId, Point sw, Point ne);

default AlbumPhotoViews getByUserIdInBox(Long userId, Point sw, Point ne) {
return new AlbumPhotoViews(
findByUserIdInBox(userId, sw, ne)
default AlbumPhotoItems getByAlbumIdInBox(Long albumId, Point sw, Point ne) {
return new AlbumPhotoItems(
findByAlbumIdInBox(albumId, sw, ne)
);
}
}
Loading
Loading

AltStyle によって変換されたページ (->オリジナル) /