Flutter 실내지도를 구현하기 까지의 여정(1)
이번에는 내가 실내지도를 구현하는데에 한 삽질을 기록해 보려고 한다.
실내지도의 기능은 마커를 달아야 하고 층별로 클릭하면 지도가 달라지고 위에 탭을 누르면 포커스가 이동해야한다.
실내지도의 레퍼런스는 아래와 같다.
우선 디자이너가 만들어준 지도의 이미지를 어떻게 지도처럼 화면에 띄울 수 있을지, 이게 가능한 지가 의문이었다. 그래서 처음엔 flutter_map이라는 패키지를 사용하기로 했다.
FlutterMap(
mapController: _mapController,
options: MapOptions(
interactionOptions: InteractionOptions(
flags: InteractiveFlag.all & ~InteractiveFlag.rotate),
initialCenter: LatLng(50, 50),
initialZoom: 1,
maxZoom: 5,
minZoom: 1,
backgroundColor: Colors.transparent,
),
children: [
TileLayer(
tileProvider: AssetTileProvider(),
urlTemplate: 'assets/tiles/floor.png',
tileSize: 256,
),
다음과 같이 options를 통해 지도의 옵션을 정할 수 있다. interactionOptions는 지도의 drag, 회전과같은 모션을 제한하거나 추가할 수 있다.
- initialCenter : 처음 시작 위치를 지정한다. 위도 경도인 LatLng으로 지정한다.
- initialZoom : 처음 줌을 의미한다.
- maxZoom : 최대 줌
- minZoom : 최소 줌
여기서 TileLayer의 tileProvider를 AssetTileProvider로 해주고 지도 이미지를 넣어주면 끝!!
인줄알았으나...
줌인아웃을 하는 순간 닥터 스트레인지를 불러야할 것 같은 광경이 펼쳐진다...
내가 생각하는거보다 지도의 메커니즘은 훨씬 복잡했고 일단 이걸 잡기 위해 검색을 해본 결과
urlTemplate: 'assets/tiles/{z}/{x}/{y}.png',
url에 이런식으로 적고 타일 파일을 다음과 같이 만든다.
먼저 url을 설명해보자면 {z}는 줌레벨을 의미한다. 그래서 만약 줌레벨을 0~5로 하고싶다면 0/0/0 이런형태의 파일구조를 5/x/x까지 만들면 된다. 줌레벨이 0일때는 0/0/0.png 줌레벨이 1이면 1/0/0.png , 1/0/1.png, 1/1/0.png 1/1/1.png 이런식으로 4^줌레벨 만큼의 사진 파일이 필요한것이다.
여기서 줌레벨 1의 4개의 사진은 정확히 4등분된 파일이 들어가야 한다.
이렇게 준비하여 돌려보니....
도르마무 현상이 일어나지 않는다.