NASA API로 소행성 지도 만들기
30710 단어 reactgraphqljavascript
이 문서에서 우리는 NASA의 API를 이용하여 소행성 지도를 만들 것이다.이것은 우리에게 얼마나 많은 소행성이 지구에 접근하고 얼마나 큰지 보여줄 것이다.나중에 볼 수 있도록 이 그림들을 클라우드 나리에 저장할 것입니다.
초기 설정
코드를 작성하기 전에, 우리는 몇 가지 일을 해야 한다.우선, NASA 소행성의 API 키가 필요합니다. 우리가 사용할 NeoWs API입니다.할 수 있다get a free one here.입력한 e-메일에 API 키를 보냅니다.
다음은 나중에 참고할 수 있도록 소행성 지도 이미지를 저장하는 클라우드 계정이 필요합니다.등록할 수 있습니다free account here.
우리는 로컬 Postgres 데이터베이스를 사용할 것입니다. 따라서 설치하지 않으면 download it here 할 수 있습니다.
현재 우리는 이미 이 모든 물건들을 설치했기 때문에 우리는 이 응용 프로그램을 개발하기 시작할 수 있다.
새로운 홍목 프로젝트 생성
터미널에서 다음 명령을 실행합니다.
$ yarn create redwood-app asteroid-map
이것은 당신을 위해 많은 새 파일과 디렉터리를 만들 것입니다.Dell은 web
및 api
폴더에 중점을 두고 있습니다.web
폴더는 React에서 모든 전단 코드를 작성할 곳입니다.api
폴더는 Postgres 연결과GraphQL 백엔드를 처리하는 곳입니다.데이터베이스 모드 및 연결 만들기
우리는 먼저 데이터베이스에 연결하고 모델을 설정할 것이다.먼저 프로젝트 루트 디렉토리의
.env
파일을 엽니다.주석이 떨어진 줄을 볼 수 있습니다. DATABASE_URL
이 줄에 대한 주석을 취소하고 로컬 연결 문자열과 일치하도록 업데이트합니다.이것은 다음과 유사하게 보일 수 있습니다.DATABASE_URL=postgres://postgres:admin@localhost:5432/asteroids
새 데이터베이스를 수동으로 만들 필요가 없습니다.첫 번째 마이그레이션을 실행하면 데이터베이스asteroids
가 만들어집니다.이제 우리는 데이터베이스를 위해 모델을 작성할 수 있다.
api > db
폴더에서 schema.prisma
를 엽니다.Redwood은 데이터베이스 작업을 처리하기 위해 Prisma를 사용합니다.이 파일에서, 우리는 연결 문자열을 사용하고 모든 테이블을 컴파일합니다.provider
값을 sqlite
에서 postgresql
로 업데이트합니다.Primsa가 Postgres 인스턴스를 처리하고 있음을 알려줍니다.앞에서 설정한 DATABASE_URL
값에서 연결 문자열을 읽는 위치를 볼 수 있습니다.그런 다음 예제 모델을 삭제하고 다음 항목으로 대체할 수 있습니다.
model Map {
id Int @id @default(autoincrement())
name String
startDate DateTime
endDate DateTime
mapUrl String
}
이 모델은 우리가 데이터베이스에 저장할 데이터를 나타낸다.NASA API는 우리가 제출한 날짜에 따라 소행성 정보를 반환하므로 이를 저장해 어떤 날짜가 소행성 지도에 해당하는지 파악한다.데이터베이스 마이그레이션 실행
기왕 우리가 표를 위해 모델을 준비했으니 우리는 소행성 지도를 그 안에 저장할 것이다. 그러면 우리는 데이터베이스 이전을 계속 실행할 것이다.터미널에서 다음 명령을 실행합니다.
$ yarn redwood prisma migrate dev
이것은 데이터베이스를 만들고 (필요할 경우) 그 안에 Map
표를 추가합니다.GraphQL 유형 및 파서 작성
이것이 바로 우리가 이 응용 프로그램의 데이터베이스에서 해야 할 모든 것이다.이제 GraphQL 서버로 전환할 수 있습니다.Redwood의 CLI에는 많은 명령이 있어 많은 작업을 수행할 수 있습니다.다음 명령을 사용하여 백엔드에 유형 및 파서를 생성합니다.
$ yarn redwood generate sdl --crud map
이것은 지도의 모든 CRUD 기능을 처리하는 데 사용할 몇 개의 파일을 생성할 것입니다.NASA API에서 가져온 데이터 유형과 데이터를 가져오는 파서를 추가하기만 하면 됩니다.소행성 데이터 형식 추가
api > src > graphql
디렉터리에서 새로 생성된 maps.sdl.ts
파일을 엽니다.이것은 CRUD 조회의 유형 정의와 데이터베이스를 업데이트하는 데 사용할 수 있는 돌연변이가 있습니다.이제 API에서 얻을 데이터, API로 보낼 입력 유형 및 데이터를 반환할 수 있는 질의를 정의하는 유형을 추가합니다.
Map
유형의 바로 아래에 다음 코드를 추가합니다.type Asteroid {
missDistance: String
estimatedDiameter: String
}
input AsteroidInput {
startDate: Date!
endDate: Date!
viewDate: Date!
}
type Query {
asteroids(input: AsteroidInput): [Asteroid] @requireAuth
maps: [Map!]! @requireAuth
map(id: Int!): Map @requireAuth
}
이것은 우리가 조회와 필요한 내용을 방문할 수 있게 할 것이다.이 데이터를 얻기 위해 해상도를 정의합시다.파서를 통해 NASA API 호출
이곳은 GraphQL에서 가장 멋있는 곳 중의 하나다.파서에서 다른 API를 호출할 수 있습니다. 데이터는 같은 단점을 통해 전송됩니다. 마치 데이터베이스에 접근하고 있는 것처럼.
api > src > services > maps
에서 maps.js
파일을 엽니다.이것은 앞서 실행한 CLI 명령에 따라 생성된 CRUD 파서입니다.이 모든 아래에 다음 파서를 추가하여 소행성 데이터를 가져옵니다.export const asteroids = ({ input }) => {
return fetch(`https://api.nasa.gov/neo/rest/v1/feed?start_date=${input.startDate.toISOString().split('T')[0]}&end_date=${input.endDate.toISOString().split('T')[0]}&api_key=${your_api_key_really_goes_here}`)
.then(response => {
return response.json()
})
.then(rawData => {
const data = rawData.near_earth_objects[input.viewDate.toISOString().split('T')[0]]
const asteroids = data.map(value => {
return {
missDistance: value.close_approach_data[0].miss_distance.kilometers,
estimatedDiameter: value.estimated_diameter.kilometers.estimated_diameter_max
}
})
return asteroids
})
}
이 해상도는 입력을 받아서 API에 요청을 보냅니다.많은 API 요청과 마찬가지로 입력을 특정 형식으로 보내야 합니다.이것이 바로 우리가 현재 방식으로 날짜 문자열을 나누어야 하는 이유이다.GraphQL은 NASA API가 싫어하는 형식으로 날짜를 전달합니다.그리고 우리는 응답에서 데이터를 얻고 우리가 지나간
viewDate
위 부근의 소행성을 살폈다.이 날짜는 시작 날짜와 종료 날짜 사이의 언제든지 사용할 수 있습니다.API에서 반환된 데이터를 가져와 필요한 값을 추출했습니다. 이것이 바로 성공적인 응답에 전달된 값입니다.이게 백엔드의 전부야!우리는 소행성 데이터를 가져와 데이터베이스에 저장하는 데 필요한 모든 종류와 해상도를 가지고 있다.우리는 주의력을 앞쪽으로 돌릴 수 있다. 거기서 우리는 일을 끝낼 것이다.
사용자 인터페이스 구성
그냥 뛰어들래요.우리가 만든 소행성 지도를 저장하기 위해서, 우리는 소프트웨어 패키지를 설치해야 한다.터미널에서
web
디렉토리로 이동하여 다음을 실행합니다.$ yarn add html-to-image
이것은 우리로 하여금 소행성 지도의 이미지를 매우 신속하게 포착할 수 있게 할 것이다.적목 CLI를 사용하여 소행성 지도 페이지를 생성할 수 있습니다.따라서 터미널에서 프로젝트의 루트 디렉토리를 반환하고 다음 명령을 실행합니다.
$ yarn redwood generate page asteroid
이것은 Routes.tsx
파일을 업데이트하여 새로운 경로를 가지게 하고 web > src > pages > AsteroidPage
에서 파일을 생성합니다.우리가 처리해야 할 서류는 AsteroidPage.tsx
이다.이 파일을 열고 기존 가져오기 문을 모두 삭제하고 다음 문구로 대체합니다.import { useQuery, useMutation } from '@redwoodjs/web'
import { useState, useRef } from 'react'
import { toPng } from 'html-to-image'
이 가져오기 후에 GraphQL 조회를 추가하여 소행성 데이터와 변이를 얻어 지도를 클라우드 inary와 데이터베이스에 저장할 수 있습니다.const CREATE_MAP_MUTATION = gql`
mutation CreateMapMutation($input: CreateMapInput!) {
createMap(input: $input) {
id
}
}
`
const GET_ASTEROIDS = gql`
query GetAsteroids($input: AsteroidInput!) {
asteroids(input: $input) {
missDistance
estimatedDiameter
}
}
`
구성 요소에 상태 추가 및 연결 사용
모든 가져오기와GraphQL 정의가 완료되면
AsteroidPage
구성 요소 내부에서 작업을 시작합니다.구성 요소의 모든 내용을 삭제할 수 있습니다. 왜냐하면 우리는 많은 다른 코드를 작성할 것입니다.우리는 우선 구성 요소에 필요한 상태와 다른 연결을 추가할 것입니다.
const [createMap] = useMutation(CREATE_MAP_MUTATION)
const canvasRef = useRef(null)
const [startDate, setStartDate] = useState("2021-08-12")
const [endDate, setEndDate] = useState("2021-08-15")
const [viewDate, setViewDate] = useState("2021-08-13")
const { loading, data } = useQuery(GET_ASTEROIDS, {
variables: { input: { startDate: startDate, endDate: endDate, viewDate: viewDate }},
})
우선, 우리는 변이를 진행하고 데이터베이스에 새로운 기록을 추가하는 방법을 만들었다.그리고 소행성 지도의 그림을 저장하기 위해 canvas ref를 설정합니다.다음에 우리는 몇 개의 다른 날짜 상태를 설정한다.이것은 우리가 저장한 지도의 내용과 응용 프로그램에서 볼 수 있는 내용을 조정할 것입니다.그 다음은 데이터 검색.NASA API에서 소행성 데이터를 가져오는 데 사용되는 해상도를 호출했습니다.우리 후단 유형에 정의된 형상 전송
input
.이 값들은 각 주에서 왔기 때문에 주 값이 변화하기만 하면 우리는 새로운 소행성 지도를 얻을 수 있다.로드 상태의
우리는
loading
호출에서 useQuery
값을 얻었다는 것을 알 수 있습니다.이것은 우리가 여전히 데이터를 추출하고 있는지 여부를 알려줄 것이다.중요한 것은 어떤 요소가 사용자에게 페이지가 불러오고 있음을 알려주는 것이다.이것은 또한 응용 프로그램이 데이터를 사용할 수 없을 때 충돌하는 것을 방지할 수 있다.데이터 조회 아래에 다음 코드를 추가합니다.if (loading) {
return <div>Loading...</div>
}
이것은 페이지에 불러오는 메시지만 표시합니다.렌더링된 요소
이제 우리는 페이지에 보여야 할 내용을 위해 되돌아오는 문장을 작성할 수 있는 데이터가 생겼다.로드 상태 확인 아래에 다음 코드를 추가하여 확인합니다.
return (
<>
<h1>AsteroidPage</h1>
<form onSubmit={submit}>
<div>
<label htmlFor="mapName">Map Name</label>
<input type="text" name="mapName" />
</div>
<div>
<label htmlFor="startDate">Start Date</label>
<input type="date" name="startDate" />
</div>
<div>
<label htmlFor="endDate">End Date</label>
<input type="date" name="endDate" />
</div>
<div>
<label htmlFor="viewDate">View Date</label>
<input type="date" name="viewDate" />
</div>
<button type="submit">Save Asteroid Map</button>
</form>
<button type="button" onClick={makeAsteroidMap}>View Map</button>
<canvas id="asteroidMap" ref={canvasRef} height="3000" width="3000"></canvas>
</>
)
일이 그렇게 많아 보이지 않는다.소행성 지도의 이름과 데이터와 그림을 가져오는 데 필요한 날짜를 입력하는 데 사용되는 목록이 있습니다.이 폼에는 우리의 입력에 따라 새로운 소행성 데이터를 가져오고 새 지도를 저장하는 제출 단추가 있습니다.아래에 있는 캔버스 요소에서 소행성 지도를 볼 수 있는 단추가 하나 더 있다.canvas 원소는 우리가 위의
useRef
갈고리 중의 목표이다.표와 보기 지도 단추는 우리가 작성해야 할 기능을 가지고 있다.지금까지의 프로그램을 보려면 터미널에서 실행하십시오
yarn redwood dev
.너는 이런 물건을 보아야 한다.커밋 기능
이 함수는 불러오는 상태 검사의 바로 아래에 추가됩니다.이것은 폼 데이터를 가져와 날짜 상태를 업데이트하고 캔버스에 소행성 지도의 스냅샷을 찍어 클라우드 나리에 올린 다음 새로운 데이터베이스 기록을 만들 것이다.
async function submit(e) {
e.preventDefault()
const mapName = e.currentTarget.mapName.value
const startDate = e.currentTarget.startDate.value
const endDate = e.currentTarget.endDate.value
const viewDate = e.currentTarget.viewDate.value
setStartDate(startDate)
setEndDate(endDate)
setViewDate(viewDate)
if (canvasRef.current === null) {
return
}
const dataUrl = await toPng(canvasRef.current, { cacheBust: true })
const uploadApi = `https://api.cloudinary.com/v1_1/${cloudName}/image/upload`
const formData = new FormData()
formData.append('file', dataUrl)
formData.append('upload_preset', upload_preset_value)
const cloudinaryRes = await fetch(uploadApi, {
method: 'POST',
body: formData,
})
const input = {
name: mapName,
startDate: new Date(startDate),
endDate: new Date(endDate),
mapUrl: cloudinaryRes.url
}
createMap({
variables: { input },
})
}
Cloudinary 콘솔에서 가져오고cloudName
사전 설정 값을 업로드해야 합니다.남은 유일한 기능은 화포에 소행성 지도를 그리는 것이다.소행성 지도 그리기
이것은 페이지 왼쪽의 서로 다른 거리에 서로 다른 크기의 동그라미를 만들어서 지구와 얼마나 가깝고 큰지 보여 줍니다.
function makeAsteroidMap() {
if (canvasRef.current.getContext) {
let ctx = canvasRef.current.getContext('2d')
data.asteroids.forEach((asteroid) => {
const scaledDistance = asteroid.missDistance / 75000
const scaledSize = asteroid.estimatedDiameter * 100
let circle = new Path2D()
circle.arc(scaledDistance * 2, scaledDistance, scaledSize, 0, 2 * Math.PI)
ctx.fill(circle)
})
}
}
이곳의 축소는 어떤 특정한 것에 기초한 것이 아니므로 수학을 마음대로 사용하세요!현재 프로그램을 실행하고 지도 보기 단추를 누르면 비슷한 내용을 볼 수 있습니다.
날짜를 업데이트하면 다른 지도를 보고 데이터베이스에 저장할 수 있습니다.이것이 바로 이 응용 프로그램의 모든 코드다!
지금 너는 우리가 매일 소행성 사건과 얼마나 가까운지 볼 수 있다.
완료된 코드
asteroid-map
folder of this repo에서 전체 항목을 볼 수 있습니다.아니면 this Code Sandbox의 앞부분을 보셔도 됩니다.값이 적용되려면 값을 업데이트해야 합니다.결론
외부 API를 사용하는 것은 우리가 자주 하는 일이고GraphQL은 우리가 모든 호출된 API를 집중할 수 있는 방법 중의 하나이다.그것을 도구로 삼아 우리는 매일 소행성에 맞는 거리를 직관적으로 보여줄 수 있다. 이것은 이 기능을 사용하는 흥미로운 방식이다.
Reference
이 문제에 관하여(NASA API로 소행성 지도 만들기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/flippedcoding/creating-an-asteroid-map-with-a-nasa-api-4afc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)