프로젝트
Flutter Map으로 여행 반경 설정
TMJeti
2025. 4. 17. 16:57
UI를 띄우는것 까지는 문제없었는데 매번 반경을 설정하는데 있어 문제가 발생했다. 분명 줌 인, 줌 아웃을 해서 반경을 새로 설정했는데 매번 필터링에 실패하고 전체 장소들이 추천되어지는 것이었다.
FlutterMap(
mapController: _mapController,
options: MapOptions(
initialCenter: currentCenter,
initialZoom: 13,
onPositionChanged: (position, _) {
setState(() {
currentCenter = position.center!;
});
},
),
children: [
TileLayer(
userAgentPackageName: 'com.example.travelapp',
),
],
),
// 💙 지도 가운데 고정된 파란 원
Container(
width: 200, // 지름 (pixel 기준) – 필요 시 조절
height: 200,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.3),
shape: BoxShape.circle,
border: Border.all(color: Colors.blueAccent, width: 2),
),
),
그렇다. 이 지도는 줌 인, 줌 아웃을 할 수는 있지만 실제 설정된 반경은 전혀 변하지 않았던 것이다 (...)
단순히 200px 원을 지도 중심에 올리는 것일 뿐이다.
근데 난 줌 레벨도 고려하여 반경을 설정하고 싶다!
FlutterMap에서 distance → 화면상 픽셀 길이로 변환하는 계산을 직접 해줘야한다.
즉, 줌(zoom) 레벨과 위도(latitude)를 이용해서 반지름(px)을 구해야 한다.
줌에 따라 px/미터 계산
double metersPerPixel(double zoom, double latitude){
return 156543.03392 * cos(latitude * pi / 180) / pow(2, zoom);
}
// 지도의 줌 레벨에 따른 픽셀 당 미터 수 계산
double getActualRadiusKm({
required double zoom,
required double latitude,
required double circleVisualDiameterPx,
}) {
final meterPerPixel = metersPerPixel(zoom, latitude);
final radiusInMeters = (circleVisualDiameterPx / 2) * meterPerPixel;
return radiusInMeters / 1000;
}
FlutterMap(
mapController: _mapController,
options: MapOptions(
initialCenter: currentCenter,
initialZoom: currentZoom,
onPositionChanged: (position, hasGesture) {
setState(() {
currentCenter = position.center!;
currentZoom = position.zoom!;
});
},
),
children: [
TileLayer(
urlTemplate:
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'com.example.travelapp',
),
],
),
// 고정된 크기의 파란 원
Container(
width: visualCircleSizePx,
height: visualCircleSizePx,
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.3),
shape: BoxShape.circle,
border: Border.all(color: Colors.blueAccent, width: 2),
),
),
visualCircleSizePx 은 실제 나오는 파란원의 크기이다. 필자는 160px 로 설정해놨다.
실제로 실행해보면
잘 된다 ^o^ 은행동에 있는 으능정이문화의거리 까지만 잘 가져왔다.
이제 가운데 파란색 원은 고정이고, 사용자가 지도를 움직여 원안에 맞추면 반경을 가져올수 있다.
필터링 기능이 모쪼록 잘 해결되어서 다행이다. 이제 관건은 이 부분이다.
반경을 너무 좁게 설정해버리면 장소 추천해주는 기능에 장소가 몇 개 없어 보다시피 볼거 없는(...) 코스를 추천해주는 한계가 생긴다. 사용자에게 반경을 설정하게 하는것이 아니라 어차피 그 지역에 가고싶다면 가고 싶은 장소 하나쯤은 있을테니 그 장소 주위 20km 이내에 있는 장소들을 뽑아와서 추천해주는 것도 나쁘지 않겠다.