Skip to content

Commit 42ef277

Browse files
authored
Merge pull request #39 from CodeForPittsburgh/fix-map
update map component
2 parents e432cf9 + 1dd78f7 commit 42ef277

2 files changed

Lines changed: 57 additions & 60 deletions

File tree

app/components/Map/cityPin.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

app/components/Map/index.js

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,11 @@
77
import React, { memo } from 'react';
88
import _ from 'lodash';
99

10-
import ReactMapGL, { Marker, Popup } from 'react-map-gl';
10+
import ReactMapGL, { Source, Layer, Popup } from 'react-map-gl';
1111
import axios from 'axios';
1212
import MapSelect from './mapSelect';
1313
import { townArray } from './townConstants';
1414
import CityInfo from './cityInfo';
15-
import CityPin from './cityPin';
1615
import Wrapper from './Wrapper';
1716

1817
/* eslint-disable react/prefer-stateless-function */
@@ -30,14 +29,15 @@ class Map extends React.PureComponent {
3029
},
3130
selectedTown: 'Pittsburgh',
3231
popupInfo: null,
33-
sites: [],
3432
};
33+
34+
this.handleClick = this.handleClick.bind(this);
3535
}
3636

3737
componentDidMount() {
3838
axios
3939
.get('https://dev.stevesaylor.io/api/location/')
40-
.then(res => this.setState({ sites: res.data }));
40+
.then(res => this.setState({ geoJSON: this.convertToGeoJSON(res) }));
4141
}
4242

4343
handleSelection(event) {
@@ -55,23 +55,45 @@ class Map extends React.PureComponent {
5555
});
5656
}
5757

58-
renderCityMarker = (city, index) => {
59-
if (city.longitude) {
60-
return (
61-
<Marker
62-
key={`marker-${index}`}
63-
longitude={city.longitude}
64-
latitude={city.latitude}
65-
>
66-
<CityPin
67-
size={20}
68-
onClick={() => this.setState({ popupInfo: city })}
69-
/>
70-
</Marker>
71-
);
72-
}
73-
return true;
74-
};
58+
convertToGeoJSON({ data }) {
59+
// Converts api data to geoJSON points
60+
// Might be better if this arrived from the server in this format
61+
return {
62+
type: 'FeatureCollection',
63+
features: data.reduce((result, site) => {
64+
const { latitude, longitude } = site;
65+
if (longitude) {
66+
result.push({
67+
type: 'Feature',
68+
geometry: {
69+
type: 'Point',
70+
// GeoJSON takes lat/lon in reverse order
71+
// Even more confusing: at least half of the lat/lon values provided are reversed??
72+
// Not sure how this wasn't a problem with previous config
73+
coordinates:
74+
longitude < latitude
75+
? [longitude, latitude]
76+
: [latitude, longitude],
77+
},
78+
properties: site,
79+
});
80+
}
81+
return result;
82+
}, []),
83+
};
84+
}
85+
86+
handleClick(event) {
87+
// Filter out features that we didn't provide
88+
const features = event.features
89+
? event.features.filter(feature => feature.layer.id === 'data')
90+
: [];
91+
if (!features.length) return;
92+
// If there are still several features, pick one at random
93+
// Future: might be better to calculate which is closest to cursor
94+
const index = Math.floor(Math.random() * features.length);
95+
this.setState({ popupInfo: features[index].properties });
96+
}
7597

7698
renderPopup() {
7799
const { popupInfo } = this.state;
@@ -103,10 +125,22 @@ class Map extends React.PureComponent {
103125
<ReactMapGL
104126
{...this.state.viewport}
105127
onViewportChange={viewport => this.setState({ viewport })}
128+
onClick={this.handleClick}
129+
clickRadius={10}
106130
mapboxApiAccessToken="pk.eyJ1IjoiaHlwZXJmbHVpZCIsImEiOiJjaWpra3Q0MnIwMzRhdGZtNXAwMzRmNXhvIn0.tZzUmF9nGk2h28zx6PM13w"
107131
>
108-
{this.state.sites.map(this.renderCityMarker)}
109-
132+
{!!this.state.geoJSON && (
133+
<Source type="geojson" data={this.state.geoJSON}>
134+
<Layer
135+
type="symbol"
136+
id="data"
137+
layout={{
138+
'icon-image': 'marker-15',
139+
'icon-allow-overlap': true,
140+
}}
141+
/>
142+
</Source>
143+
)}
110144
{this.renderPopup()}
111145
</ReactMapGL>
112146
</Wrapper>

0 commit comments

Comments
 (0)