diff --git a/app/components/Map/cityPin.js b/app/components/Map/cityPin.js
deleted file mode 100644
index 02a299b..0000000
--- a/app/components/Map/cityPin.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-const ICON = `M20.2,15.7L20.2,15.7c1.1-1.6,1.8-3.6,1.8-5.7c0-5.6-4.5-10-10-10S2,4.5,2,10c0,2,0.6,3.9,1.6,5.4c0,0.1,0.1,0.2,0.2,0.3
-c0,0,0.1,0.1,0.1,0.2c0.2,0.3,0.4,0.6,0.7,0.9c2.6,3.1,7.4,7.6,7.4,7.6s4.8-4.5,7.4-7.5c0.2-0.3,0.5-0.6,0.7-0.9
-C20.1,15.8,20.2,15.8,20.2,15.7z`;
-
-const pinStyle = {
- cursor: 'pointer',
- fill: '#d00',
- stroke: 'none',
-};
-
-export default class CityPin extends React.PureComponent {
- render() {
- const { size = 20, onClick } = this.props;
-
- return (
-
- );
- }
-}
-
-CityPin.propTypes = {
- size: PropTypes.number,
- onClick: PropTypes.func,
-};
diff --git a/app/components/Map/index.js b/app/components/Map/index.js
index b47deb3..1d6104a 100644
--- a/app/components/Map/index.js
+++ b/app/components/Map/index.js
@@ -7,12 +7,11 @@
import React, { memo } from 'react';
import _ from 'lodash';
-import ReactMapGL, { Marker, Popup } from 'react-map-gl';
+import ReactMapGL, { Source, Layer, Popup } from 'react-map-gl';
import axios from 'axios';
import MapSelect from './mapSelect';
import { townArray } from './townConstants';
import CityInfo from './cityInfo';
-import CityPin from './cityPin';
import Wrapper from './Wrapper';
/* eslint-disable react/prefer-stateless-function */
@@ -30,14 +29,15 @@ class Map extends React.PureComponent {
},
selectedTown: 'Pittsburgh',
popupInfo: null,
- sites: [],
};
+
+ this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
axios
.get('https://dev.stevesaylor.io/api/location/')
- .then(res => this.setState({ sites: res.data }));
+ .then(res => this.setState({ geoJSON: this.convertToGeoJSON(res) }));
}
handleSelection(event) {
@@ -55,23 +55,45 @@ class Map extends React.PureComponent {
});
}
- renderCityMarker = (city, index) => {
- if (city.longitude) {
- return (
-
- this.setState({ popupInfo: city })}
- />
-
- );
- }
- return true;
- };
+ convertToGeoJSON({ data }) {
+ // Converts api data to geoJSON points
+ // Might be better if this arrived from the server in this format
+ return {
+ type: 'FeatureCollection',
+ features: data.reduce((result, site) => {
+ const { latitude, longitude } = site;
+ if (longitude) {
+ result.push({
+ type: 'Feature',
+ geometry: {
+ type: 'Point',
+ // GeoJSON takes lat/lon in reverse order
+ // Even more confusing: at least half of the lat/lon values provided are reversed??
+ // Not sure how this wasn't a problem with previous config
+ coordinates:
+ longitude < latitude
+ ? [longitude, latitude]
+ : [latitude, longitude],
+ },
+ properties: site,
+ });
+ }
+ return result;
+ }, []),
+ };
+ }
+
+ handleClick(event) {
+ // Filter out features that we didn't provide
+ const features = event.features
+ ? event.features.filter(feature => feature.layer.id === 'data')
+ : [];
+ if (!features.length) return;
+ // If there are still several features, pick one at random
+ // Future: might be better to calculate which is closest to cursor
+ const index = Math.floor(Math.random() * features.length);
+ this.setState({ popupInfo: features[index].properties });
+ }
renderPopup() {
const { popupInfo } = this.state;
@@ -103,10 +125,22 @@ class Map extends React.PureComponent {
this.setState({ viewport })}
+ onClick={this.handleClick}
+ clickRadius={10}
mapboxApiAccessToken="pk.eyJ1IjoiaHlwZXJmbHVpZCIsImEiOiJjaWpra3Q0MnIwMzRhdGZtNXAwMzRmNXhvIn0.tZzUmF9nGk2h28zx6PM13w"
>
- {this.state.sites.map(this.renderCityMarker)}
-
+ {!!this.state.geoJSON && (
+
+
+
+ )}
{this.renderPopup()}