Skip to content

Commit

Permalink
feat(map-markers): add markers and zoom map to fit markers
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewglover committed Nov 14, 2016
1 parent 6fdb8f1 commit d63af4b
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
74 changes: 70 additions & 4 deletions app/components/google_map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* global google */
import React, { Component, PropTypes } from 'react';
import { map, reduce } from 'ramda';

const style = {
googleMap: {
Expand All @@ -8,24 +9,89 @@ const style = {
},
};

const buildMarker = ({ position, title }) =>
new google.maps.Marker({
position,
title,
});

const buildMarkers = map(buildMarker);

const LatLngObj =
PropTypes.shape({
lat: PropTypes.number.isRequired,
lng: PropTypes.number.isRequired,
});


class GoogleMap extends Component {

static propTypes = {
position: PropTypes.array.isRequired,
position: LatLngObj.isRequired,
zoom: PropTypes.number.isRequired,
markerData: PropTypes.arrayOf(PropTypes.object).isRequired,
}

static defaultProps = {
markerData: [],
}

constructor() {
super();
this.markers = [];
}

componentDidMount() {
this.privateSetMap();
this.privateBuildMarkers();
this.privateShowMarkers();
this.privateFitMarkersOnMap();
}

privateSetMapCanvas = (mapCanvas) => {
this.mapCanvas = mapCanvas;
}

privateSetMap() {
const mapOptions = {
center: new google.maps.LatLng(...this.props.position),
center: this.props.position,
zoom: this.props.zoom,
};

this.map = new google.maps.Map(this.mapCanvas, mapOptions);
}

privateSetMapCanvas = (mapCanvas) => {
this.mapCanvas = mapCanvas;
privateDeleteMarkers() {
this.privateClearMarkers();
this.markers = [];
}

privateBuildMarkers() {
this.privateDeleteMarkers();
this.markers = buildMarkers(this.props.markerData);
}

privateShowMarkers() {
this.privateSetMapForMarkers(this.map);
}

privateClearMarkers() {
this.privateSetMapForMarkers(null);
}

privateSetMapForMarkers(mapRef) {
this.markers.forEach(marker => marker.setMap(mapRef));
}

privateFitMarkersOnMap() {
this.map.fitBounds(this.markerBounds);
}

get markerBounds() {
return reduce(
(bounds, marker) => bounds.extend(marker.getPosition()),
new google.maps.LatLngBounds(),
this.markers);
}

render() {
Expand Down
11 changes: 11 additions & 0 deletions app/components/place_map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow
import React, { PropTypes } from 'react';
import { map } from 'ramda';
import GoogleMap from './google_map';

const style = {
Expand All @@ -10,12 +11,22 @@ const style = {
},
};

const placeToMarker = ({ place_id, name, location }) =>
({
id: place_id,
position: location,
title: name,
});

const toMarkerData = map(placeToMarker);

const PlaceMap = ({ places, location }: { places: Object[], location: Number[] }) =>
(places.length > 0
? (<div style={style.map}>
<GoogleMap
position={location}
zoom={16}
markerData={toMarkerData(places)}
/>
</div>)
: null);
Expand Down
11 changes: 9 additions & 2 deletions app/components/places.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,22 @@ import * as fromReducers from '../reducers';
import PlaceList from './place_list';
import PlaceMap from './place_map';


const LatLngObj =
PropTypes.shape({
lat: PropTypes.number.isRequired,
lng: PropTypes.number.isRequired,
});


const SimplePlaces = ({ places, view, location }) =>
(view === 'list'
? <PlaceList places={places} location={location} />
: <PlaceMap places={places} location={location} />);

SimplePlaces.propTypes = {
places: PropTypes.arrayOf(PropTypes.object),
location: PropTypes.arrayOf(PropTypes.number),
location: LatLngObj,
view: PropTypes.string.isRequired,
};

Expand All @@ -36,7 +44,6 @@ const getSimplePlaces =

const getLocation =
compose(
({ lat, lng }) => [lat, lng],
defaultTo({ lat: 0, lng: 0 }),
fromReducers.getLocationForSelectedLocality);

Expand Down

0 comments on commit d63af4b

Please sign in to comment.