地図アプリ作成

# 概要
フロントエンドにReact、バックエンドにNode.js(expressサーバー)、DBはHerokuPostgresの環境で地図アプリを作成
開発環境については下記参照
[Node.js+React+Herokuでアプリ開発環境を構築する](https://qiita.com/kubota_ndatacom/items/c62109ad6e570085af88)
[Heroku Postgresとアプリの接続設定](https://qiita.com/kubota_ndatacom/items/4d6ec524ae5c5d42a8f3)
[アプリ作成時に使用したReactのライブラリ](https://qiita.com/kubota_ndatacom/items/f9340c2fc5792ad56605)

# 目次
[1. メイン画面と概要](#1-メイン画面と概要)
[2. 非ログイン時の機能](#2-非ログイン時の機能)
[3. ユーザー権限でのログイン時の機能](#3-ユーザー権限でのログイン時の機能)
[4. 管理者権限でのログイン時の機能](#4-管理者権限でのログイン時の機能)
[5. 地図を画面に表示する機能の実装方法](#5-地図を画面に表示する機能の実装方法)


# 1. メイン画面と概要

![1-01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/6be6dc91-858b-080f-3172-3f041c8a9c16.jpeg)

地図上にマーカーを登録する(詳細及び、タグを登録する)
タグで絞り込み機能により、絞り込んだタグのマーカのみ表示可能
ユーザー毎にマーカーをお気に入り登録でき、一覧表示時にて優先表示させる事が可能

※マーカ登録及びお気に入り機能はユーザー登録が必要、マーカーを表示(タグ絞り込み)は非ログインでも可能

# 2. 非ログイン時の機能
タグの絞り込み表示

![1-03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/c047e9e3-9d68-9ed1-83b1-247b747c9e53.jpeg)


マーカー一覧表示

![1-05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/5a710e00-dc22-0b1d-a793-d53c55629c58.jpeg)


# 3. ユーザー権限でのログイン時の機能
マーカーを登録(タグ付け)

![1-02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/427e494e-b241-445a-c4f0-32758a697a1a.jpeg)


マーカー一覧表示(+ユーザー単位のお気に入り機能)

![1-04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/d8faa1e9-b82b-e4b2-fc5d-f9f4120d624c.jpeg)


# 4. 管理者権限でのログイン時の機能
タグ管理

![1-06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/7e84f08f-9d72-6b50-6175-ae459d5dc828.jpeg)


ユーザー管理

![1-07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2749195/288f720e-6f9a-33a6-c6b5-e691bf907c18.jpeg)

# 5. 地図を画面に表示する機能の実装方法
react-leafletを使って地図描写を実装する

ライブラリのインストールを実行
```
$ npm install leaflet react-leaflet
```

MapContainerでマップオブジェクトを作成、TileLayerで地図を表示する
TileLayerを用いてOpenStreetMap地図データを表示する
※今回はopenstreetmapを使って地図を描写する

``` javascript:App.js
import React,{ useState,useEffect,useRef,Component } from 'react';
import { MapContainer, Marker, Popup, TileLayer, useMapEvents } from 'react-leaflet';
import { LatLng } from 'leaflet';
import 'leaflet/dist/leaflet.css';
import Leaflet from 'leaflet';
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

function App = () => {
  // 緯度軽度
  const [position, setPosition] = useState(new LatLng(34.732938, 135.498543));
  // 初期マップズームレベル
  const [zoomLevel, setZoomLevel] = useState(18);

  const onClickEdit = () =>{
    // ポップアップクリック時の処理
  }

  return (
    <MapContainer center={position} zoom={zoomLevel} style={{ height: '80vh' }}>
      <TileLayer
        attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <Marker position={markerPos}>
        <Popup>
          <div onClick={() => onClickEdit()}>
            <span><b>[MarkerTitle]</b></span>
          </div>
        </Popup>
      </Marker>
    </MapContainer>
  )
};
export default App;
```

現在位置を取得する方法

ライブラリのインストールを実行
```
$ npm install react-router-dom
```

navigator.geolocationから緯度・経度を取得出来る
※ただし、IPアドレスからのおおよその位置取得になるので精度は良くない

``` javascript:App.js
import { useHistory,useLocation } from 'react-router-dom';

function App = () => {
  const [position, setPosition] = useState(new LatLng(34.732938, 135.498543));

  if(navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(position => {
      const { latitude, longitude } = position.coords;
      if(position!=null) {
        setPosition(new LatLng( latitude, longitude ));
      }
    });
  }
  return (
    // 略
  )
};
export default App;
```