Мои первые 6 месяцев учебы в колледже я обязана Google Maps. Вы могли бы сказать, что я не был бы там, где нахожусь сегодня, если бы этот маркер местоположения и синий путь к моему месту назначения не ладили так хорошо. Я бы тоже не был там, где сейчас. Это всего лишь точка и линия, в чем же дело? И это совершенно верно; в этом нет ничего страшного, но все благодаря хорошим ребятам из Google. Их алгоритмы вычисляют самые быстрые маршруты для езды, ходьбы и Heely (RIP) к месту назначения. Нам решать, как лучше всего использовать это в наших приложениях.

Есть много способов отобразить маршрут на Google Maps. Все, что вам действительно нужно, это немного знаний HTML (хотя вы будете использовать теги скриптов), и вы уже в пути с помощью Службы навигации Google Maps. Но я хотел воссоздать тот же мобильный опыт, который ведет меня к буррито в 3 часа ночи каждую субботу. Мое любимое оружие: React Native (Если ты не знаешь, теперь ты знаешь). Я доверяю вам изучить основы, и если вы хотите попробовать, Expo - отличный инструмент, чтобы увидеть, как ваше приложение оживает.

Компонент карты:

Мне очень хотелось бы выяснить, как реализовать Google Maps как компонент React Native, но здесь еще немного. Первый детский шаг: Компонент AirBnB's MapView. [Tl; dr: Это оболочка, которая взяла компонент MapView из React Native и дополнила его таким количеством опций и оптимизаций, что исходный компонент теперь устарел.]

//In Your Terminal (Yes, I Know You Already Know This)
npm install --save react-native-maps
//React Component (Apple Map on iOS, Google Map on Android)
import MapView from 'react-native-maps'

На этом этапе вы сможете буквально перетащить компонент ‹Mapview /› в функцию рендеринга вашего класса и получить функциональную карту (хотя вы, возможно, захотите изучить параметры, чтобы настроить внешний вид или фокус).

Полилинии, наконец

Наконец-то мы готовы поговорить о ломаных линиях. Проще говоря, полилиния - это просто смесь множества более мелких сегментов линии. Эти линейные сегменты используют значения широты и долготы для построения частей вашего пути. Соберите их все вместе, и у вас будет свой маршрут! Google Maps API помогает нам со значениями lat / lng, так что возьмите ключ API с сайта их разработчиков. Теперь простой вызов позволяет нам получить всю информацию, необходимую для построения нашей ломаной линии, и это выглядит примерно так:

https://maps.googleapis.com/maps/api/directions/json?origin=40.71855466,-73.98899738&destination=40.72867347,-74.00473773&mode=walking&key=[YOUR_API_KEY_HERE]

Идите вперед и введите это в свой браузер, чтобы увидеть, как выглядит результат. Это объект, который дает нам информацию для пешеходного маршрута (обратите внимание на параметр пешеходного перехода в URL-адресе; продолжайте, бездельничайте). Используйте то, что вам нравится (place_id позволяет получить доступ к гораздо большей информации о месте с помощью службы Google Адреса). Что нас (меня) здесь интересует, так это свойство overview_polyline, которое дает нам (слегка измененную) строку в кодировке base64. Взломайте этот код, и у вас волшебным образом останется массив объектов широты и долготы, из которых состоят ваши линейные сегменты, а затем и ваша ломаная линия. Я рекомендую проверить кодирование / декодирование base64, поскольку это более стабильный способ получения данных по сети с использованием строки общих символов.

Вот визуальное изображение ваших точек, сегментов и ломаной линии:

Достаточно поговорить

Вот простой код для работы ваших ломаных линий. Примечание: вы определенно можете сделать все это во внешнем интерфейсе, но не делайте этого. Процессоры для смартфонов по всему миру будут вам благодарны.

Реагировать:

import React, { Component } from 'react';
import { MapView } from 'expo';
import { getDirections } from '../redux'; //next section, patience
class Map extends Component {
    constructor(props) {
        super(props)
        this.state = {
//you want to locally store your start location and destination, and your polyline coordinates
        }
    }
 componentDidMount() {
//use your current location as your starting point, if you'd like. I am.
       navigator.geolocation.getCurrentPosition((res, rej) => {
//you will get a res.coords property        
res ? this.setState({ ...etc }): console.log(rej);
       });
 }
onButtonPress(){
        let { startLocation, destination } = this.state;
        getDirectionsToBar(startLocation, destination) //lat-lng objects
        .then(res=> this.setState({...set your coordinates})
        .catch(er => console.log(er))
 }
render(){
  //Make sure you set your destination (using markers or a dropdown or however you want the user to set it) and create a button
//Within your MapView
{ this.state.coordinates &&
   <MapView.Polyline
   coordinates={this.state.coordinates}
   strokeWidth={4}
   strokeColor="rgba(255,140,0,0.8)"/>
  }
}

Redux:

import axios from 'axios';
export function getDirectionsToBar(startLoc, destLoc){
    return axios.post('YOUR_ROUTE', { startLocation, destination })
      .then(res => { return res.data })
      .catch(er=>console.log(er))
}

Экспресс (ваш API):

//I'll use a router so you cant mount this code on your api path or wherever else you'd like
const router = require('express').Router();
//axios helps us make calls to the Google Maps Api
const axios = require('axios');
//mapbox gives us a great polyline tool that does the decoding for us. sorry I sent you down the base64 rabbithole. But also, you're welcome.
const Polyline = require('@mapbox/polyline');
module.exports = router;
router.post('/', (req, res, next) => {
  let { startLocation, destination } = req.body
  //remember this url? you can do an async await/fetch too
  axios.get(`https://maps.googleapis.com/maps/api/directions/json?origin=${startLocation.latitude},${startLocation.longitude}&destination=${destination.latitude},${destination.longitude}&mode=walking&key=YOUR_API_KEY`)
  .then(result=> result.data)
  .then(result=> {
    let array = Polyline.decode(result.routes[0].overview_polyline.points);
//your base64 string is now an array of lat/lng objects
    let coordinates = array.map((point) => {
              return  {
                  latitude :point[0],
                  longitude :point[1]
              }
          })
    res.send(coordinates)
  }).catch(er=>console.log(er.message))
})

Хьюстон, у нас есть ломаная линия

Вот и все. Вы хотите подумать о таких вещах, как использование расстояния и продолжительности, которые предоставляет вам Google, и предоставление пользователю возможности отменить навигацию, очистив свое состояние и добавив условия. Но это было не так уж и плохо, и теперь ты можешь найти свой собственный путь к занятиям!