React Native에서 세계 지도 보기
15409 단어 reactnativeReact자바스크립트TypeScript
소개
직장에서 React Native를 사용해 개발을 하고 있어, 지견이 모여 왔습니다만, 기사에 일으키려고 고민하고 있는 사이에 꽤 지나 버렸습니다.
이번에는 화면에 세계지도를 표시하는 방법에 관한 것입니다.
이미지는 아래와 같은 느낌입니다.
사용중인 라이브러리
d3-geo
i18n-iso-countries
react-native-svg
topojson-client
world-countries
구현 방법
우선 맵 데이터가 필요합니다.
일본지도는 조금 뼈가 부러지지만 세계지도는 이 데이터 을 사용하면 쉽게 대응할 수 있습니다.
import worldData from 'src/assets/data/world-110m.json'
import { feature } from 'topojson-client';
const WorldMapPage: React.FunctionComponent = () => {
const mapData = feature(worldData, worldData.objects.countries).features;
...
화면상에 스포트(빨간색 원)나, 나라를 채우고 싶은 경우는 아래와 같이 실장합니다.
명소
import countries from 'world-countries';
...
const WorldMapPage: React.FunctionComponent = () => {
...
const spotGeos = [
{ code: 'JPN', volume: 15 },
{ code: 'USA', volume: 30 },
];
spotGeos.reduce((acc, sg) => {
const country = countries.find((c) => c.cca3 === sg.code);
if (!country || !country.latlng) return acc;
acc.push({
coordinates: country.latlng.slice().reverse(),
volume: sg.volume,
});
return acc;
}, [] as any);
국가 색상
import isoCountries from 'i18n-iso-countries';
...
const WorldMapPage: React.FunctionComponent = () => {
...
const paintCountry = [
{ id: 'CHN' },
{ id: 'HKG' },
{ id: 'GBR' },
{ id: 'FRA' },
{ id: 'ITA' },
{ id: 'KOR' },
];
const getColor = (numericId: string) => {
const alpha3 = isoCountries.numericToAlpha3(numericId);
return paintCountry.find((c) => c.id === alpha3)
? `rgba(38,50,56,0.5)`
: `rgba(255,255,255,1)`;
};
메르카토르 다이어그램에 플롯할 수 있도록 매핑 함수를 정의합니다.
const viewWidth = 800;
const viewHeight = 450;
const projectMercator = () =>
geoMercator()
.scale(viewWidth / ((2 * Math.PI * (360 - 0)) / 360))
.center([0, 0])
.translate([viewWidth / 2, viewHeight / 2])
이것으로 준비가 완료됩니다.
그리고는 react-native-svg
를 사용해, 화면상에 묘사합니다.
<Svg
width={size}
height={size * (viewHeight / viewWidth)}
viewBox={`0 0 ${viewWidth} ${viewHeight}`}
>
<G>
{mapData.map((d, i) => {
return (
<Path
key={`path-${i}`}
d={geoPath().projection(projectMercator())(d)}
fill={`${getColor(d.id)}`}
stroke="#000000"
strokeWidth={0.5}
/>
);
})}
</G>
<G>
{spots &&
spots.length > 0 &&
spots.map((sg, i) => (
<Circle
key={`circle-${i}`}
cx={projectMercator()(sg.coordinates)[0]}
cy={projectMercator()(sg.coordinates)[1]}
r={sg.volume}
fill={`rgba(233,30,99,0.5)`}
/>
))}
</G>
</Svg>
size
는 여기에서는 화면폭을 취득해 설정하고 있습니다.
위의 단계에서 국가 채우기와지도에 원을 그릴 수있었습니다.
일본 지도를 그리려면 일본 지도에 대한 데이터를 가져와야 합니다.
또한 세계지도와 비교하여 스케일이 다르기 때문에 미세 조정이 필요합니다.
데이터만 준비할 수 있으면, 묘사는 같은 수법으로 실현 가능하게 됩니다.
결론
이번에는, 반년간, 투고가 멀어져 버렸습니다.
틈새 지식은 정리하고, 언어화하고 조금씩 기사로 할 수 있으면 좋겠습니다.
Reference
이 문제에 관하여(React Native에서 세계 지도 보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/dhythm/items/1de40673b4d2f2893abc
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import worldData from 'src/assets/data/world-110m.json'
import { feature } from 'topojson-client';
const WorldMapPage: React.FunctionComponent = () => {
const mapData = feature(worldData, worldData.objects.countries).features;
...
import countries from 'world-countries';
...
const WorldMapPage: React.FunctionComponent = () => {
...
const spotGeos = [
{ code: 'JPN', volume: 15 },
{ code: 'USA', volume: 30 },
];
spotGeos.reduce((acc, sg) => {
const country = countries.find((c) => c.cca3 === sg.code);
if (!country || !country.latlng) return acc;
acc.push({
coordinates: country.latlng.slice().reverse(),
volume: sg.volume,
});
return acc;
}, [] as any);
import isoCountries from 'i18n-iso-countries';
...
const WorldMapPage: React.FunctionComponent = () => {
...
const paintCountry = [
{ id: 'CHN' },
{ id: 'HKG' },
{ id: 'GBR' },
{ id: 'FRA' },
{ id: 'ITA' },
{ id: 'KOR' },
];
const getColor = (numericId: string) => {
const alpha3 = isoCountries.numericToAlpha3(numericId);
return paintCountry.find((c) => c.id === alpha3)
? `rgba(38,50,56,0.5)`
: `rgba(255,255,255,1)`;
};
const viewWidth = 800;
const viewHeight = 450;
const projectMercator = () =>
geoMercator()
.scale(viewWidth / ((2 * Math.PI * (360 - 0)) / 360))
.center([0, 0])
.translate([viewWidth / 2, viewHeight / 2])
<Svg
width={size}
height={size * (viewHeight / viewWidth)}
viewBox={`0 0 ${viewWidth} ${viewHeight}`}
>
<G>
{mapData.map((d, i) => {
return (
<Path
key={`path-${i}`}
d={geoPath().projection(projectMercator())(d)}
fill={`${getColor(d.id)}`}
stroke="#000000"
strokeWidth={0.5}
/>
);
})}
</G>
<G>
{spots &&
spots.length > 0 &&
spots.map((sg, i) => (
<Circle
key={`circle-${i}`}
cx={projectMercator()(sg.coordinates)[0]}
cy={projectMercator()(sg.coordinates)[1]}
r={sg.volume}
fill={`rgba(233,30,99,0.5)`}
/>
))}
</G>
</Svg>
이번에는, 반년간, 투고가 멀어져 버렸습니다.
틈새 지식은 정리하고, 언어화하고 조금씩 기사로 할 수 있으면 좋겠습니다.
Reference
이 문제에 관하여(React Native에서 세계 지도 보기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/dhythm/items/1de40673b4d2f2893abc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)