๋ค์ด๋ฒ๋งต์ ๋ฆฌ์กํธ ๋ค์ดํฐ๋ธ ๋ธ๋ฆฟ์ง์ ๋๋ค.
npm install react-native-nmap --save;
- React Native 0.60+
$ cd ios/ && pod install
- React Native <= 0.59
$ react-native link react-native-nmap
$ cd ios/ && pod install
ios์ ๊ฒฝ์ฐ
git-lfs
์ค์น๊ฐ ํ์ํฉ๋๋ค. ์ฐธ๊ณ
๋ค์ด๋ฒ ๋งต ์๋๋ก์ด๋ SDK ๋ฌธ์๋ฅผ ๋ฐ๋ผ APIํค์ ๋ ํฌ์งํฐ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํฉ๋๋ค
/android/build.gradle
ํ์ผ์ ์๋์ ๊ฐ์ด ๋ ํฌ์งํฐ๋ฆฌ๋ฅผ ์ถ๊ฐํฉ๋๋ค
allprojects {
repositories {
google()
jcenter()
// ๋ค์ด๋ฒ ์ง๋ ์ ์ฅ์
maven {
url 'https://repository.map.naver.com/archive/maven'
}
}
}
/android/app/src/AndroidManifest.xml
์ ์๋์ ๊ฐ์ด ์ถ๊ฐํ๊ณ ๋ฐ๊ธ๋ฐ์ ํด๋ผ์ด์ธํธ ์์ด๋๋ก ๋ฐ๊ฟ์ค๋๋ค.
<manifest>
<application>
<meta-data
android:name="com.naver.maps.map.CLIENT_ID"
android:value="YOUR_CLIENT_ID_HERE" />
</application>
</manifest>
๋ค์ด๋ฒ ๋งต IOS SDK ๋ฌธ์๋ฅผ ๋ฐ๋ผ APIํค์ ๋ ํฌ์งํฐ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํฉ๋๋ค.
info.plist
์ ์๋์ ๊ฐ์ด ๋ฐ๊ธ๋ฐ์ ํด๋ผ์ด์ธํธ ์์ด๋๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
<key>NMFClientId</key>
<string>YOUR_CLIENT_ID_HERE</string>
...
<dict>
<plist>
import NaverMapView, {
Circle,
Marker,
Path,
Polyline,
Polygon,
Coord,
} from "react-native-nmap";
function MyMap() {
const P0 = { latitude: 37.564362, longitude: 126.977011 };
const P1 = { latitude: 37.565051, longitude: 126.978567 };
const P2 = { latitude: 37.565383, longitude: 126.976292 };
// ์๋๋ getPointLatLng ์ฌ์ฉ์ ์ํด ์ถ๊ฐ๋ ์์ ์ฝ๋์
๋๋ค.
const getScreenLatLng = async (location: Coord) => {
const {
bottomLeftCoord,
bottomRightCoord,
topLeftCoord,
topRightCoord,
} = await nMapRef.current.getPointLatLng({
center: location,
screen: {
width: 50,
height: 50,
},
});
console.log(bottomLeftCoord, bottomRightCoord, topLeftCoord, topRightCoord);
};
return (
<NaverMapView
style={{ width: "100%", height: "100%" }}
showsMyLocationButton={true}
center={{ ...P0, zoom: 16 }}
onMove={(e) => console.warn("onMove", JSON.stringify(e.nativeEvent))}
onCameraChange={(e) => console.warn("onCameraChange", JSON.stringify(e))}
onMapClick={(e) => console.warn("onMapClick", JSON.stringify(e))}
>
<Marker coordinate={P0} onClick={() => console.warn("onClick! p0")} />
<Marker
coordinate={P1}
pinColor="blue"
onClick={async () => {
console.warn("onClick! p1");
await getScreenLatLng(P1);
}}
/>
<Marker
coordinate={P2}
pinColor="red"
onClick={() => console.warn("onClick! p2")}
/>
<Path
coordinates={[P0, P1]}
onClick={() => console.warn("onClick! path")}
width={10}
/>
<Polyline
coordinates={[P1, P2]}
onClick={() => console.warn("onClick! polyline")}
/>
<Circle
coordinate={P0}
color={"rgba(255,0,0,0.3)"}
radius={200}
onClick={() => console.warn("onClick! circle")}
/>
<Polygon
coordinates={[P0, P1, P2]}
color={`rgba(0, 0, 0, 0.5)`}
onClick={() => console.warn("onClick! polygon")}
/>
</NaverMapView>
);
}
ํ์ ์คํฌ๋ฆฝํธ ํ์ ์ ์๊ฐ ํฌํจ๋์ด ์์ด ํ์ ์คํฌ๋ฆฝํธ ์ฌ์ฉ์ ์ถ์ฒํฉ๋๋ค.
export interface Coord {
latitude: number;
longitude: number;
}
export interface Region extends Coord {
latitudeDelta: number;
longitudeDelta: number;
}
export interface Rect {
left?: number;
top?: number;
right?: number;
bottom?: number;
}
interface NaverMapViewProps {
center?: Coord & {
zoom?: number;
tilt?: number;
bearing?: number;
};
tilt?: number;
bearing?: number;
mapPadding?: Rect;
logoMargin?: Rect;
logoGravity?: Gravity;
onInitialized?: Function;
onCameraChange?: (event: {
latitude: number;
longitude: number;
zoom: number;
contentsRegion: [Coord, Coord, Coord, Coord, Coord]; // https://navermaps.github.io/android-map-sdk/reference/com/naver/maps/map/NaverMap.html#getContentRegion()
coveringRegion: [Coord, Coord, Coord, Coord, Coord];
}) => void;
onMapClick?: (event: {
x: number;
y: number;
latitude: number;
longitude: number;
}) => void;
onMove?: (event:{
nativeEvent:{
reason:number,
animated:boolean
}
}) => void;
showsMyLocationButton?: boolean;
compass?: boolean;
scaleBar?: boolean;
zoomControl?: boolean;
mapType?: MapType;
minZoomLevel?: number;
maxZoomLevel?: number;
symbolScale?: number; // 0 ~ 2 ๊น์ง๋ง ๊ฐ๋ฅ
buildingHeight?: number;
nightMode?: boolean;
scrollGesturesEnabled?: boolean;
zoomGesturesEnabled?: boolean;
tiltGesturesEnabled?: boolean;
rotateGesturesEnabled?: boolean;
stopGesturesEnabled?: boolean;
useTextureView?: boolean; // android only
}
/// component method
animateToCoordinate: (coord: Coord) => void;
animateToTwoCoordinates: (c1: Coord, c2: Coord) => void;
animateToCoordinates: (coords: Coord[], bounds?: {
top: number;
bottom: number;
left: number;
right: number;
}) => void;
animateToRegion: (region: Region) => void;
setLocationTrackingMode: (mode: number) => void;
setLayerGroupEnabled: (group: LayerGroup, enabled: boolean) => void;
showsMyLocationButton: (show: boolean) => void;
handleOnCameraChange: (event: React.SyntheticEvent<{}, {
latitude: number;
longitude: number;
zoom: number;
}>) => void;
handleOnMapClick: (event: React.SyntheticEvent<{}, {
x: number;
y: number;
latitude: number;
longitude: number;
}>) => void;
interface MarkerProps {
coordinate: Coord;
anchor?: { x: number; y: number };
pinColor?: string;
alpha?: number;
rotation?: number;
flat?: boolean;
image?: ImageSourcePropType;
onClick?: () => void;
width?: number;
height?: number;
angle?: number;
hidden?: boolean;
zIndex?: number;
iconPerspectiveEnabled?: boolean;
isHideCollidedSymbols?: boolean;
isHideCollidedMarkers?: boolean;
isHideCollidedCaptions?: boolean;
isForceShowIcon?: boolean;
caption?: {
text?: string;
align?: Align;
textSize?: number;
color?: string;
haloColor?: string;
offset?: number;
requestedWidth?: number;
minZoom?: number;
maxZoom?: number;
};
subCaption?: {
text?: string;
textSize?: number;
color?: number;
haloColor?: number;
requestedWidth?: number;
minZoom?: number;
maxZoom?: number;
};
}
์๋๋ก์ด๋ ํ๋ซํผ์์ ๋ง์ปค๋ด ์ปค์คํ ๋ทฐ๋ฅผ ์ง์ํฉ๋๋ค.
0.0.57
<Marker coordinate={P5} width={96} height={96}> <View style={{ backgroundColor: "rgba(255,0,0,0.2)", borderRadius: 80 }}> <View style={{ backgroundColor: "rgba(0,0,255,0.3)", borderWidth: 2, borderColor: "black", flexDirection: "row", }} > <Image source={require("./marker.png")} style={{ width: 32, height: 32, backgroundColor: "rgba(0,0,0,0.2)", resizeMode: "stretch", borderWidth: 2, borderColor: "black", }} fadeDuration={0} /> <Text>Image</Text> </View> <ImageBackground source={require("./marker.png")} style={{ width: 64, height: 64 }} > <Text>image background</Text> </ImageBackground> </View> </Marker>
interface PolylineProps {
coordinates: Coord[];
strokeWidth?: number;
strokeColor?: string;
onClick?: () => void;
}
interface PathProps {
coordinates: Coord[];
width?: number;
color?: string;
outlineWidth?: number;
passedColor?: string;
outlineColor?: string;
passedOutlineColor?: string;
pattern?: ImageSourcePropType;
patternInterval?: number;
onClick?: () => void;
}
export interface CircleProps {
coordinate: Coord[];
radius?: number;
color?: string;
outlineWidth?: number;
outlineColor?: string;
zIndex?: number;
onClick?: () => void;
}
export interface PolygonProps {
coordinate: Coord[];
outlineWidth?: number;
outlineColor?: string;
color?: string;
holes?: Coord[][];
onClick?: () => void;
}
export declare enum LayerGroup {
LAYER_GROUP_BUILDING = "building",
LAYER_GROUP_TRANSIT = "transit",
LAYER_GROUP_BICYCLE = "bike",
LAYER_GROUP_TRAFFIC = "ctt",
LAYER_GROUP_CADASTRAL = "landparcel",
LAYER_GROUP_MOUNTAIN = "mountain",
}
export interface PointType {
center: Coord;
screen: {
width: number;
height: number;
};
}
-
react-navigation์ ์คํ ์คํฌ๋ฆฐ ์ฌ์ฉ์ ์๋๋ก์ด๋์์ ๋งต๋ทฐ๊ฐ ๊ฒน์ณ ๋ณด์ด๋ ํ์์ด ์์ ๊ฒฝ์ฐ
useTextureView
์ต์ ์ ์ถ๊ฐํด ์ฃผ์ธ์. #27 -
์๋๋ก์ด๋์์
ScrollView
๋ด๋ถ์ ์ถ๊ฐํ ๊ฒฝ์ฐscrollGesturesEnabled
๋ฅผ ์ด์ฉํด ๋งต ์คํฌ๋กค์ ์ ์ดํ ์ ์์ต๋๋ค. #62 -
๋ง์ปค ํด๋ฌ์คํฐ๋ง์ ํ์ํ ์ง๋ ์ปจํ ์ธ ์์ญ์
onCameraChange
์ด๋ฒคํธ๋ฅผ ํตํด ์ป์ ์ ์์ต๋๋ค. #64