QuadFlask/react-native-naver-map

[기능요청] 맵 바운드 정보 API추가

2mori opened this issue · 4 comments

2mori commented

Version of react-native-naver-map libraries
0.0.58

Version of react-native
0.63.49

클러스터링 성능 개선을 위해 맵 바운드 정보를 얻고 싶습니다.

아래 두 API를 사용하고 싶습니다.

https://navermaps.github.io/android-map-sdk/reference/com/naver/maps/map/NaverMap.html#getContentBounds()

getContentBounds() | 지도의 콘텐츠 영역에 대한 LatLngBounds를 반환합니다.
getCoveringBounds() | 콘텐츠 패딩을 포함한 지도의 뷰 전체 영역에 대한 LatLngBounds를 반환합니다.

근본적인 해결책은 아니지만 제가 바운드를 얻는 코드를 공유합니다.
임시로 사용하세요~

import {Dimensions} from 'react-native';

const deviceWidth = Dimensions.get('screen').width;
const deviceHeight = Dimensions.get('screen').height;

const getBounds = (center, zoomlevel) => {
  const zoomLevel2LatLng =
    256 / (Math.round(Math.pow(2, zoomlevel) * 1000) / 1000);
  const pixel2LatLng = (pixel) => {
    return (pixel / 1024) * zoomLevel2LatLng;
  };
  let points = [
    //NorthEast
    {
      lat: center.latitude + pixel2LatLng(deviceHeight),
      lng: center.longitude + pixel2LatLng(deviceWidth * 1.5),
    },
    //SouthWest
    {
      lat: center.latitude - pixel2LatLng(deviceHeight),
      lng: center.longitude - pixel2LatLng(deviceWidth) * 1.5,
    },
  ];
  return points;
};
2mori commented

이 코드에 대해 간략히 설명해주실 수 있을까요? 정확도가 어느정도가 될까요?

이 코드에 대해 간략히 설명해주실 수 있을까요? 정확도가 어느정도가 될까요?

//지도 전체 영역에 대한 bound를 획득합니다.
const getMapBounds = (
  center, //구하고자 하는 지도 영역의 센터값입니다.
  zoomlevel, //현재 지도의 줌 레벨입니다.
  mapWidth, //지도의 길이값입니다. 픽셀단위입니다.
  mapHeight, //지도의 높이값입니다. 픽셀단위입니다.
) => {
  // 네이버 지도 기본 줌레벨은 16입니다.
  // zoom level이 16일때 1px : 1m로 가정합니다.
  // 참조: https://d2.naver.com/helloworld/1174
  // 참조: https://www.ncloud.com/support/notice/all/738
  const metersPerPixel = Math.pow(2, 16 - zoomlevel);
  // 1m 당 위도 변화 : 1 / ((2*pi*지구반지름(m)) / 360(degree))
  const deltaLatPerMeter = 0.00000899321;
  // 1m 당 경도 변화 : 1 / cos(위도)((2*pi*지구반지름(m)) / 360(degree))
  const deltaLngPerMeter =
    deltaLatPerMeter / Math.cos((center.latitude * Math.PI) / 180);
  //맵 중앙으로부터 상하 bound 까지의 거리입니다.
  // (맵 높이 / 2)(pixels) * (meteres/pixel) * (deltaLat / meter) = 상하 위도 차이. 
  const deltaLat = (mapHeight / 2) * metersPerPixel * deltaLatPerMeter;
  //맵 중앙으로부터 좌우 bound 까지의 거리입니다.
  // (맵 길이 / 2)(pixels) * (meteres/pixel) * (deltaLat / meter) = 좌우 경도 차이.
  const deltaLng = (mapWidth / 2) * metersPerPixel * deltaLngPerMeter;
  let points = [
    //NorthEast
    {
      lat: center.latitude + deltaLat,
      lng: center.longitude + deltaLng,
    },
    //SouthWest
    {
      lat: center.latitude - deltaLat,
      lng: center.longitude - deltaLng,
    },
  ];
  return points;
};

좀더 개선된 버전의 코드입니다. 그런데 이제 설명을 곁들인
정확도는 아무래도 projectile 계산이 없기도하고 100%는 아니지만 사용하시는데 큰 무리는 없을겁니다.
다만 정확히 바운드는 아니니 요청하신 기능이 구현될 때 까지만 임시로 쓰시는걸 추천드려요~

0.0.66 버전에 업데이트하였습니다.
따로 함수호출해서 받아오는건 번거로울것 같아 카메라 이동 이벤트 핸들러에 추가하였습니다.

onCameraChange?: (event: {
        latitude: number;
        longitude: number;
        zoom: number;
+       contentsRegion: [Coord, Coord, Coord, Coord, Coord];
+       coveringRegion: [Coord, Coord, Coord, Coord, Coord];
}) => void;