From 94eabe953bf721f8bfbaa9dc1025430a1759eeda Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Fri, 14 Sep 2018 00:35:40 +0200 Subject: [PATCH] exif map component --- gatsby-node.js | 23 +++++- package.json | 3 + src/components/atoms/Exif.jsx | 100 +++++++++++++++++++++----- src/components/atoms/Exif.module.scss | 17 ++++- src/templates/Post.jsx | 4 ++ 5 files changed, 128 insertions(+), 19 deletions(-) diff --git a/gatsby-node.js b/gatsby-node.js index 3e2372a6..14248d57 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -5,6 +5,7 @@ const { createFilePath } = require('gatsby-source-filesystem') const { paginate } = require('gatsby-awesome-pagination') const fastExif = require('fast-exif') const Fraction = require('fraction.js') +const dms2dec = require('dms2dec') const meta = yaml.load(fs.readFileSync('./content/meta.yml', 'utf8')) const { itemsPerPage } = meta @@ -79,6 +80,12 @@ const createExifFields = (exifData, createNodeField, node) => { FocalLength, ExposureBiasValue } = exifData.exif + const { + GPSLatitudeRef, + GPSLatitude, + GPSLongitudeRef, + GPSLongitude + } = exifData.gps const { n, d } = new Fraction(ExposureTime) const exposureShortened = parseFloat(ExposureBiasValue.toFixed(2)) @@ -89,6 +96,16 @@ const createExifFields = (exifData, createNodeField, node) => { const shutterspeed = `${n}/${d}s` const focalLength = `${FocalLength}mm` + const GPSdec = dms2dec( + GPSLatitude, + GPSLatitudeRef, + GPSLongitude, + GPSLongitudeRef + ) + + const latitude = GPSdec[0] + const longitude = GPSdec[1] + let exposure if (ExposureBiasValue === 0) { @@ -109,7 +126,11 @@ const createExifFields = (exifData, createNodeField, node) => { fstop, shutterspeed, focalLength, - exposure + exposure, + gps: { + latitude, + longitude + } } }) } diff --git a/package.json b/package.json index d783707a..e4ffee3e 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "last 3 versions" ], "dependencies": { + "dms2dec": "^1.1.0", "fast-exif": "^1.0.1", "fraction.js": "^4.0.9", "gatsby": "^2.0.0-rc.21", @@ -49,6 +50,8 @@ "intersection-observer": "^0.5.0", "node-sass": "^4.9.3", "nord": "^0.2.1", + "pigeon-maps": "^0.10.4", + "pigeon-marker": "^0.3.4", "prismjs": "^1.15.0", "react": "^16.5.0", "react-clipboard.js": "^2.0.0", diff --git a/src/components/atoms/Exif.jsx b/src/components/atoms/Exif.jsx index 0efeed4c..ed874498 100644 --- a/src/components/atoms/Exif.jsx +++ b/src/components/atoms/Exif.jsx @@ -1,24 +1,92 @@ -import React from 'react' +import React, { Fragment, PureComponent } from 'react' import PropTypes from 'prop-types' +import Map from 'pigeon-maps' +import Marker from 'pigeon-marker/react' import styles from './Exif.module.scss' -const Exif = ({ exif }) => { - const { iso, model, fstop, shutterspeed, focalLength, exposure } = exif +const MAPBOX_ACCESS_TOKEN = + 'pk.eyJ1Ijoia3JlbWFsaWNpb3VzIiwiYSI6ImNqbTE2NHpkYjJmNm8zcHF4eDVqZzk3ejEifQ.1uwPzM6MSTgL2e1Hxcmuqw' - return ( - - ) +const mapbox = (mapboxId, accessToken) => (x, y, z) => { + const retina = + typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : '' + return `https://api.mapbox.com/styles/v1/mapbox/${mapboxId}/tiles/256/${z}/${x}/${y}${retina}?access_token=${accessToken}` } -Exif.propTypes = { - exif: PropTypes.object +const providers = { + osm: (x, y, z) => { + const s = String.fromCharCode(97 + ((x + y + z) % 3)) + return `https://${s}.tile.openstreetmap.org/${z}/${x}/${y}.png` + }, + wikimedia: (x, y, z) => { + const retina = + typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : '' + return `https://maps.wikimedia.org/osm-intl/${z}/${x}/${y}${retina}.png` + }, + stamen: (x, y, z) => { + const retina = + typeof window !== 'undefined' && window.devicePixelRatio >= 2 ? '@2x' : '' + return `https://stamen-tiles.a.ssl.fastly.net/terrain/${z}/${x}/${y}${retina}.jpg` + }, + streets: mapbox('streets-v10', MAPBOX_ACCESS_TOKEN), + satellite: mapbox('satellite-streets-v10', MAPBOX_ACCESS_TOKEN), + outdoors: mapbox('outdoors-v10', MAPBOX_ACCESS_TOKEN), + light: mapbox('light-v9', MAPBOX_ACCESS_TOKEN), + dark: mapbox('dark-v9', MAPBOX_ACCESS_TOKEN) } -export default Exif +class MapExif extends PureComponent { + static propTypes = { + gps: PropTypes.object + } + + render() { + const { latitude, longitude } = this.props.gps + + return ( + + {}} /> + + ) + } +} + +export default class Exif extends PureComponent { + static propTypes = { + exif: PropTypes.object + } + + render() { + const { + iso, + model, + fstop, + shutterspeed, + focalLength, + exposure, + gps + } = this.props.exif + + return ( + + + + ) + } +} diff --git a/src/components/atoms/Exif.module.scss b/src/components/atoms/Exif.module.scss index d463b4af..af3c2ea5 100644 --- a/src/components/atoms/Exif.module.scss +++ b/src/components/atoms/Exif.module.scss @@ -2,10 +2,13 @@ @import 'mixins'; .exif { + margin-top: -($spacer); + margin-bottom: $spacer * 2; +} + +.data { font-size: $font-size-mini; color: $brand-grey-light; - margin-top: -($spacer * 1.25); - margin-bottom: $spacer * 2; display: flex; flex-wrap: wrap; text-align: center; @@ -30,3 +33,13 @@ } } } + +.map { + @include breakoutviewport; + + border-radius: $border-radius; + overflow: hidden; + margin-top: $spacer / 2; + border: 1px solid $brand-grey-dimmed; + height: 160px; +} diff --git a/src/templates/Post.jsx b/src/templates/Post.jsx index 09a9569d..08fd4333 100644 --- a/src/templates/Post.jsx +++ b/src/templates/Post.jsx @@ -81,6 +81,10 @@ export const pageQuery = graphql` shutterspeed focalLength exposure + gps { + latitude + longitude + } } } }