Improved SelectionMap

This commit is contained in:
vjrj 2017-12-11 18:23:24 +01:00
parent 2ef2fee802
commit 29f9a2d476
5 changed files with 106 additions and 76 deletions

View file

@ -1,12 +1,14 @@
import { Meteor } from 'meteor/meteor'; import { Meteor } from 'meteor/meteor';
import { ReactiveVar } from 'meteor/reactive-var';
const geolocation = new ReactiveVar(); const geolocation = new ReactiveVar();
Meteor.startup(function() { Meteor.startup(() => {
Meteor.call("geo", function (error, response) { Meteor.call('geo', (error, response) => {
if (error) { if (error) {
console.warn(error); console.warn(error);
} else { } else {
var pos = [ const pos = [
response.location.latitude, response.location.latitude,
response.location.longitude response.location.longitude
]; ];

View file

@ -30,6 +30,7 @@ class DistanceSlider extends React.Component {
}; };
this.onSliderChange = this.onSliderChange.bind(this); this.onSliderChange = this.onSliderChange.bind(this);
this.onAfterChange = this.onAfterChange.bind(this); this.onAfterChange = this.onAfterChange.bind(this);
this.props.onChange(10);
} }
onSliderChange(value) { onSliderChange(value) {

View file

@ -1,8 +1,13 @@
/* global setTimeout */
/* eslint-disable react/jsx-indent-props */
/* eslint-disable import/no-absolute-path */
import React, { Component } from 'react'; import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Map, TileLayer, Marker, CircleMarker, Circle } from 'react-leaflet'; import { Map, TileLayer, Marker, CircleMarker, Circle } from 'react-leaflet';
import Leaflet from 'leaflet'; import Leaflet from 'leaflet';
import { translate } from 'react-i18next'; import { translate } from 'react-i18next';
import { withTracker } from 'meteor/react-meteor-data';
import update from 'immutability-helper';
import geolocation from '/imports/startup/client/geolocation'; import geolocation from '/imports/startup/client/geolocation';
import 'leaflet-graphicscale/dist/Leaflet.GraphicScale.min.css'; import 'leaflet-graphicscale/dist/Leaflet.GraphicScale.min.css';
import 'leaflet-graphicscale/dist/Leaflet.GraphicScale.min.js'; import 'leaflet-graphicscale/dist/Leaflet.GraphicScale.min.js';
@ -25,11 +30,11 @@ class SelectionMap extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
center: geolocation.get(), center: props.center,
marker: geolocation.get(), marker: props.center,
zoom: 11, zoom: 11,
draggable: true, distance: props.distance,
modified: false draggable: true
}; };
this.getMap = this.getMap.bind(this); this.getMap = this.getMap.bind(this);
@ -41,8 +46,21 @@ class SelectionMap extends Component {
} }
componentDidMount() { componentDidMount() {
if (this.isValidState()) {
this.addScale(); this.addScale();
} }
}
componentWillReceiveProps(nextProps) {
const nextCenter = nextProps.center[0] ? nextProps.center : this.state.center;
const nextMarker = nextProps.center[0] ? nextProps.center : this.state.marker;
this.setState({
center: nextCenter,
marker: nextMarker,
distance: nextProps.distance || this.state.distance
});
this.fit();
}
componentDidUpdate() { componentDidUpdate() {
this.fit(); this.fit();
@ -58,20 +76,19 @@ class SelectionMap extends Component {
updatePosition() { updatePosition() {
const { lat, lng } = this.marker.leafletElement.getLatLng(); const { lat, lng } = this.marker.leafletElement.getLatLng();
// console.log(`New marker lat ${lat} and lng ${lng}`);
const currentDistance = this.state.distance; const currentDistance = this.state.distance;
this.setState({ this.setState(update(this.state, { $merge: { marker: [lat, lng] } }));
marker: [lat, lng],
modified: true
});
console.log(currentDistance);
this.props.onSelection({ lat, lng, currentDistance }); this.props.onSelection({ lat, lng, currentDistance });
this.fit(); this.fit();
} }
fit() { fit() {
// console.log("fit!"); // console.log("fit!");
if (this.selectionMap && this.distanceCircle) {
this.getMap().fitBounds(this.distanceCircle.leafletElement.getBounds(), [70, 70]); this.getMap().fitBounds(this.distanceCircle.leafletElement.getBounds(), [70, 70]);
} }
}
addScale() { addScale() {
// https://www.npmjs.com/package/leaflet-graphicscale // https://www.npmjs.com/package/leaflet-graphicscale
@ -91,23 +108,27 @@ class SelectionMap extends Component {
); );
} }
isValidState() {
return this.state.center && this.state.center[0] && this.state.distance;
}
render() { render() {
this.state.center = !this.state.modified && this.props.lat? [this.props.lat, this.props.lng]: this.state.center; // console.log('render map called');
this.state.marker = !this.state.modified && this.props.lat? [this.props.lat, this.props.lng]: this.state.marker;
this.state.distance = !this.state.modified? this.props.distance: this.state.distance;
this.state.modified = false;
return ( return (
<div> <div>
{ this.state && this.state.center && { this.isValidState() &&
<Map center={this.state.center} zoom={this.state.zoom} <Map
center={this.state.center}
zoom={this.state.zoom}
ref={(map) => { this.selectionMap = map; }} ref={(map) => { this.selectionMap = map; }}
sleep={window.location.pathname === '/'} sleep={window.location.pathname === '/'}
sleepTime={10750} sleepTime={10750}
wakeTime={750} wakeTime={750}
sleepNote={true} sleepNote
hoverToWake={true} hoverToWake
wakeMessage={this.props.t('Pulsa para activar')} wakeMessage={this.props.t('Pulsa para activar')}
sleepOpacity={.6}> sleepOpacity={0.6}
>
<TileLayer <TileLayer
attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors" attribution="&amp;copy <a href=&quot;http://osm.org/copyright&quot;>OpenStreetMap</a> contributors"
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
@ -117,25 +138,32 @@ class SelectionMap extends Component {
onDragend={this.updatePosition} onDragend={this.updatePosition}
position={this.state.marker} position={this.state.marker}
icon={positionIcon} icon={positionIcon}
title={this.props.t("Arrastrar para seleccionar otro punto")} title={this.props.t('Arrastrar para seleccionar otro punto')}
ref={(ref) => { this.marker = ref; }}> ref={(ref) => { this.marker = ref; }}
</Marker> />
<CircleMarker <CircleMarker
center={this.state.marker} color="red" center={this.state.marker}
color="red"
stroke={false} stroke={false}
fillOpacity="1" fillOpacity="1"
fill={true} fill
radius={3} /> radius={3}
<Circle center={this.state.marker} />
<Circle
center={this.state.marker}
ref={(ref) => { this.distanceCircle = ref; }} ref={(ref) => { this.distanceCircle = ref; }}
color="#145A32" color="#145A32"
fillColor="green" fillColor="green"
fillOpacity={.1} fillOpacity={0.1}
radius={this.state.distance * 1000} /> radius={this.state.distance * 1000}
/>
<Control position="topright" > <Control position="topright" >
<ButtonToolbar> <ButtonToolbar>
<Button bsStyle="success" onClick={(event) => this.doSubs(event)}> <Button
{this.props.t("Subscribirme a fuegos en este rádio")} bsStyle="success"
onClick={event => this.doSubs(event)}
>
{this.props.t('Subscribirme a fuegos en este rádio')}
</Button> </Button>
</ButtonToolbar> </ButtonToolbar>
</Control> </Control>
@ -144,16 +172,16 @@ class SelectionMap extends Component {
); );
} }
} }
SelectionMap.defaultProps = {
distance: 10
};
SelectionMap.propTypes = { SelectionMap.propTypes = {
history: PropTypes.object.isRequired, history: PropTypes.object.isRequired,
lat: PropTypes.number, t: PropTypes.func.isRequired,
lng: PropTypes.number, center: PropTypes.array,
distance: PropTypes.number, distance: PropTypes.number,
onSelection: PropTypes.func.isRequired onSelection: PropTypes.func.isRequired
}; };
export default translate([], { wait: true })(SelectionMap); export default translate([], { wait: true })(withTracker(props => ({
center: props.center[0] ? props.center : geolocation.get(),
distance: props.distance
}))(SelectionMap));

View file

@ -67,8 +67,7 @@ class FireSubscription extends React.Component {
</Row> </Row>
<Row className="align-items-center justify-content-center"> <Row className="align-items-center justify-content-center">
<SelectionMap <SelectionMap
lat={this.state.lat} center={[this.state.lat, this.state.lng]}
lng={this.state.lng}
distance={this.state.distance} distance={this.state.distance}
history={this.props.history} history={this.props.history}
onSelection={(state) => this.onSelection(state)} onSelection={(state) => this.onSelection(state)}

View file

@ -9,10 +9,10 @@ class SubsAutocomplete extends React.Component {
super(props); super(props);
this.state = { this.state = {
address: '', address: '',
} };
} }
onChange = (address) => { this.setState({ address }) } onChange = (address) => { this.setState({ address }); }
handleSelect = (address) => { handleSelect = (address) => {
const self = this; const self = this;