Improved firesmap
This commit is contained in:
parent
4c5aef6e4f
commit
56a7468ae3
7 changed files with 214 additions and 132 deletions
|
|
@ -1,15 +1,17 @@
|
||||||
/* global Counter */
|
/* global Counter */
|
||||||
/* eslint-disable import/no-absolute-path */
|
/* eslint-disable import/no-absolute-path */
|
||||||
|
/* eslint-disable prefer-arrow-callback */
|
||||||
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { check, Match } from 'meteor/check';
|
import { check, Match } from 'meteor/check';
|
||||||
import IPGeocoder from '/imports/startup/server/IPGeocoder';
|
import { localize } from '/imports/startup/server/IPGeocoder';
|
||||||
import ActiveFires from '../ActiveFires';
|
import ActiveFires from '../ActiveFires';
|
||||||
|
|
||||||
const counter = new Counter('countActiveFires', ActiveFires.find({}));
|
const counter = new Counter('countActiveFires', ActiveFires.find({}));
|
||||||
|
|
||||||
|
Meteor.publish('activefirestotal', function total() {
|
||||||
Meteor.publish('activefirestotal', () => counter);
|
return counter;
|
||||||
|
});
|
||||||
|
|
||||||
const validZoom = Match.Where((zoom) => {
|
const validZoom = Match.Where((zoom) => {
|
||||||
// http://wiki.openstreetmap.org/wiki/Zoom_levels
|
// http://wiki.openstreetmap.org/wiki/Zoom_levels
|
||||||
|
|
@ -54,9 +56,9 @@ const activefires = (zoom, lat, lng, height, width) => {
|
||||||
const distUnt = resolution * Math.max(height, width);
|
const distUnt = resolution * Math.max(height, width);
|
||||||
const distance = Math.trunc(distUnt);
|
const distance = Math.trunc(distUnt);
|
||||||
// console.log(`so ${height}x${width} gives ${Math.trunc(resolution*height/1000)} x ${Math.trunc(resolution*width/1000)} km, so looking in ${distance}`);
|
// console.log(`so ${height}x${width} gives ${Math.trunc(resolution*height/1000)} x ${Math.trunc(resolution*width/1000)} km, so looking in ${distance}`);
|
||||||
console.log(`so ${height}x${width} gives ${resolution} of resolution, so looking in ${distance}`);
|
console.log(`So ${height}x${width} gives ${Math.trunc(resolution)} of resolution, so looking in ${Math.trunc(distance / 1000)}km`);
|
||||||
|
|
||||||
return ActiveFires.find({
|
const fires = ActiveFires.find({
|
||||||
ourid: {
|
ourid: {
|
||||||
$near: {
|
$near: {
|
||||||
$geometry: {
|
$geometry: {
|
||||||
|
|
@ -74,9 +76,42 @@ const activefires = (zoom, lat, lng, height, width) => {
|
||||||
scan: 1
|
scan: 1
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
console.log(`Fires total: ${fires.count()}`);
|
||||||
|
return fires;
|
||||||
};
|
};
|
||||||
|
|
||||||
Meteor.publish('activefiresmyloc', (zoom, lat, lng, height, width) => {
|
|
||||||
|
Meteor.publish('allActiveFires', function allActive() {
|
||||||
|
// latitude -90 and 90 and the longitude between -180 and 180
|
||||||
|
|
||||||
|
const { latitude, longitude } = localize().location;
|
||||||
|
console.log(`${latitude}, ${longitude}`);
|
||||||
|
check(latitude, NumberBetween(-90, 90));
|
||||||
|
check(longitude, NumberBetween(-180, 180));
|
||||||
|
// https://docs.meteor.com/api/collections.html#Mongo-Collection-find
|
||||||
|
return ActiveFires.find({
|
||||||
|
ourid: {
|
||||||
|
$near: {
|
||||||
|
$geometry: {
|
||||||
|
type: 'Point',
|
||||||
|
coordinates: [longitude, latitude]
|
||||||
|
},
|
||||||
|
$minDistance: 0,
|
||||||
|
$maxDistance: 1000 // 156412000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
fields: {
|
||||||
|
_id: 0,
|
||||||
|
lat: 1,
|
||||||
|
lon: 1,
|
||||||
|
scan: 1
|
||||||
|
},
|
||||||
|
maxTimeMs: 30000
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.publish('activefiresmyloc', function activeInMyLoc(zoom, lat, lng, height, width) {
|
||||||
check(zoom, validZoom);
|
check(zoom, validZoom);
|
||||||
check(lat, NullOr(Number));
|
check(lat, NullOr(Number));
|
||||||
check(lng, NullOr(Number));
|
check(lng, NullOr(Number));
|
||||||
|
|
@ -84,19 +119,8 @@ Meteor.publish('activefiresmyloc', (zoom, lat, lng, height, width) => {
|
||||||
check(width, NullOr(Number));
|
check(width, NullOr(Number));
|
||||||
console.log(`Check active fires in ${lat},${lng} with zoom ${zoom} pixels in ${height}x${width} map`);
|
console.log(`Check active fires in ${lat},${lng} with zoom ${zoom} pixels in ${height}x${width} map`);
|
||||||
if (lat === null || lng === null) {
|
if (lat === null || lng === null) {
|
||||||
let clientIP;
|
const location = localize();
|
||||||
if (this.connection && this.connection.clientAddress) {
|
console.log(`${location.latitude}, ${location.longitude}`);
|
||||||
clientIP = this.connection.clientAddress;
|
|
||||||
} else {
|
|
||||||
console.warn('We cannot get this meteor connection IP');
|
|
||||||
clientIP = '127.0.0.1';
|
|
||||||
}
|
|
||||||
if (clientIP === '127.0.0.1') {
|
|
||||||
clientIP = '80.58.61.250'; // Some Spain IP address
|
|
||||||
}
|
|
||||||
// https://www.npmjs.com/package/maxmind
|
|
||||||
const location = IPGeocoder.get(clientIP);
|
|
||||||
console.log(location);
|
|
||||||
return activefires(zoom, location.latitude, location.longitude, height, width);
|
return activefires(zoom, location.latitude, location.longitude, height, width);
|
||||||
}
|
}
|
||||||
return activefires(zoom, lat, lng, height, width);
|
return activefires(zoom, lat, lng, height, width);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
|
/* eslint-disable prefer-arrow-callback */
|
||||||
|
|
||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import maxmind from 'maxmind';
|
import maxmind from 'maxmind';
|
||||||
|
|
||||||
|
process.env.HTTP_FORWARDED_COUNT = Meteor.settings.private.proxies_count;
|
||||||
|
if (!Meteor.isDevelopment) {
|
||||||
|
console.log(`Number or proxies (needed for client IP lookup): ${process.env.HTTP_FORWARDED_COUNT}`);
|
||||||
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/13969655/how-do-you-check-whether-the-given-ip-is-internal-or-not
|
// https://stackoverflow.com/questions/13969655/how-do-you-check-whether-the-given-ip-is-internal-or-not
|
||||||
function isPrivateIP(ip) {
|
function isPrivateIP(ip) {
|
||||||
const parts = ip.split('.');
|
const parts = ip.split('.');
|
||||||
|
|
@ -13,11 +20,16 @@ function isPrivateIP(ip) {
|
||||||
const IPGeocoder = maxmind.openSync(`${process.env.PWD}/private/GeoLite2-City.mmdb`);
|
const IPGeocoder = maxmind.openSync(`${process.env.PWD}/private/GeoLite2-City.mmdb`);
|
||||||
export default IPGeocoder;
|
export default IPGeocoder;
|
||||||
|
|
||||||
Meteor.methods({
|
// Warning: Meteor cannot access to this.connection with arrow functions
|
||||||
geo() {
|
export function localize() {
|
||||||
// https://stackoverflow.com/questions/14843232/how-to-get-the-user-ip-address-in-meteor-server/22657421#22657421
|
// https://stackoverflow.com/questions/14843232/how-to-get-the-user-ip-address-in-meteor-server/22657421#22657421
|
||||||
let clientIP = this.connection.clientAddress;
|
let clientIP;
|
||||||
|
if (this.connection && this.connection.clientAddress) {
|
||||||
|
clientIP = this.connection.clientAddress;
|
||||||
|
} else {
|
||||||
|
console.warn(`We cannot get this meteor connection IP for this connection (${this.connection})`);
|
||||||
|
clientIP = '127.0.0.1';
|
||||||
|
}
|
||||||
if (isPrivateIP(clientIP)) {
|
if (isPrivateIP(clientIP)) {
|
||||||
clientIP = '80.58.61.250'; // Some Spain IP address
|
clientIP = '80.58.61.250'; // Some Spain IP address
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +40,10 @@ Meteor.methods({
|
||||||
const location = IPGeocoder.get(clientIP);
|
const location = IPGeocoder.get(clientIP);
|
||||||
// console.log(location);
|
// console.log(location);
|
||||||
return location;
|
return location;
|
||||||
},
|
}
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
geo: localize,
|
||||||
getMapKey() {
|
getMapKey() {
|
||||||
// http://meteorpedia.com/read/Environment_Variables
|
// http://meteorpedia.com/read/Environment_Variables
|
||||||
// https://developers.google.com/maps/documentation/javascript/get-api-key
|
// https://developers.google.com/maps/documentation/javascript/get-api-key
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,17 @@ export default function FireList(props) {
|
||||||
const {
|
const {
|
||||||
fires, scale, useMarkers, nasa
|
fires, scale, useMarkers, nasa
|
||||||
} = props;
|
} = props;
|
||||||
const items = fires.map(({ _id, ...otherProps }) => {
|
const useMarks = useMarkers && scale;
|
||||||
if (useMarkers && scale) {
|
const usePixel = !nasa || !scale;
|
||||||
return (<FireIconMark key={_id} nasa={nasa} {...otherProps} />);
|
/* console.log(`Using marks: ${useMarks}, using pixels: ${usePixel}`); */
|
||||||
|
let items;
|
||||||
|
if (useMarks) {
|
||||||
|
items = fires.map(({ _id, ...otherProps }) => (<FireIconMark key={_id} nasa={nasa} {...otherProps} />));
|
||||||
|
} else if (usePixel) {
|
||||||
|
items = fires.map(({ _id, ...otherProps }) => (<FirePixel key={_id} nasa={nasa} {...otherProps} />));
|
||||||
|
} else {
|
||||||
|
items = fires.map(({ _id, ...otherProps }) => (<FireCircleMark key={_id} nasa={nasa} {...otherProps} />));
|
||||||
}
|
}
|
||||||
if (!nasa && !scale) {
|
|
||||||
return (<FirePixel key={_id} nasa={nasa} {...otherProps} />);
|
|
||||||
}
|
|
||||||
return (<FireCircleMark key={_id} nasa={nasa} {...otherProps} />);
|
|
||||||
});
|
|
||||||
return (<div style={{ display: 'none' }}>{items}</div>);
|
return (<div style={{ display: 'none' }}>{items}</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,19 @@
|
||||||
|
/* eslint-disable react/jsx-indent-props */
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CircleMarker } from 'react-leaflet';
|
import { CircleMarker } from 'react-leaflet';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
/* Less acurate (1 pixel per fire) but faster */
|
/* Less acurate (1 pixel per fire) but faster */
|
||||||
const FirePixel = ({ lat, lon, nasa }) => (
|
const FirePixel = ({ lat, lon, nasa }) => (
|
||||||
<CircleMarker center={[lat, lon]} color={nasa ? 'red' : '#D35400'} stroke={false} fillOpacity="1" fill radius={2} />
|
<CircleMarker
|
||||||
|
center={[lat, lon]}
|
||||||
|
color={nasa ? 'red' : '#D35400'}
|
||||||
|
stroke={false}
|
||||||
|
fillOpacity="1"
|
||||||
|
fill
|
||||||
|
radius={nasa ? 1 : 2}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ const Navigation = props => (
|
||||||
</Navbar.Brand>
|
</Navbar.Brand>
|
||||||
{/* <Navbar.Toggle/> */}
|
{/* <Navbar.Toggle/> */}
|
||||||
<button className="sr-only navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
<button className="sr-only navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span className="navbar-toggler-icon"></span>
|
<span className="navbar-toggler-icon" />
|
||||||
</button>
|
</button>
|
||||||
</Navbar.Header>
|
</Navbar.Header>
|
||||||
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
|
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<span className="navbar-toggler-icon"></span>
|
<span className="navbar-toggler-icon" />
|
||||||
</button>
|
</button>
|
||||||
{/* <Navbar.Collapse> */}
|
{/* <Navbar.Collapse> */}
|
||||||
<div className="collapse navbar-collapse" id="navbarNavDropdown">
|
<div className="collapse navbar-collapse" id="navbarNavDropdown">
|
||||||
|
|
@ -35,7 +35,7 @@ const Navigation = props => (
|
||||||
</LinkContainer> */}
|
</LinkContainer> */}
|
||||||
<LinkContainer className="nav-item" anchorClassName="nav-link" to="/subscriptions">
|
<LinkContainer className="nav-item" anchorClassName="nav-link" to="/subscriptions">
|
||||||
<NavItem eventKey={1.2} href="/subscriptions">
|
<NavItem eventKey={1.2} href="/subscriptions">
|
||||||
{props.authenticated ? <Trans>Mis alertas</Trans>:<Trans>Participar</Trans>}
|
{props.authenticated ? <Trans>Mis alertas</Trans> : <Trans>Participar</Trans>}
|
||||||
</NavItem>
|
</NavItem>
|
||||||
</LinkContainer>
|
</LinkContainer>
|
||||||
<LinkContainer className="nav-item" anchorClassName="nav-link" to="/fires">
|
<LinkContainer className="nav-item" anchorClassName="nav-link" to="/fires">
|
||||||
|
|
|
||||||
|
|
@ -31,13 +31,11 @@ import './FiresMap.scss';
|
||||||
const { BaseLayer } = LayersControl;
|
const { BaseLayer } = LayersControl;
|
||||||
|
|
||||||
const MAXZOOM = 6;
|
const MAXZOOM = 6;
|
||||||
|
const MAXZOOMREACTIVE = 6;
|
||||||
const zoom = new ReactiveVar(8);
|
const zoom = new ReactiveVar(8);
|
||||||
const lat = new ReactiveVar();
|
const center = new ReactiveVar([null, null]);
|
||||||
const lng = new ReactiveVar();
|
const mapSize = new ReactiveVar([400, 400]);
|
||||||
const height = new ReactiveVar(400);
|
|
||||||
const width = new ReactiveVar(400);
|
|
||||||
|
|
||||||
// TODO share only the used part of fires data
|
|
||||||
// Remove map in subscription
|
// Remove map in subscription
|
||||||
class FiresMap extends React.Component {
|
class FiresMap extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
|
@ -62,11 +60,26 @@ class FiresMap extends React.Component {
|
||||||
Gkeys.load((err, key) => {
|
Gkeys.load((err, key) => {
|
||||||
self.setState({ gkey: key });
|
self.setState({ gkey: key });
|
||||||
});
|
});
|
||||||
height.set(this.divElement.clientHeight);
|
mapSize.set([this.divElement.clientHeight, this.divElement.clientWidth]);
|
||||||
width.set(this.divElement.clientWidth);
|
|
||||||
this.addScale();
|
this.addScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* componentWillReceiveProps(nextProps) {
|
||||||
|
* if (nextProps.loading) {
|
||||||
|
* // console.log('Loading new fires');
|
||||||
|
* }
|
||||||
|
* // this.setState({ loading: nextProps.loading });
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
* if (nextProps.loading) {
|
||||||
|
* return true; // false;
|
||||||
|
* }
|
||||||
|
* return true;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
onViewportChanged(viewport) {
|
onViewportChanged(viewport) {
|
||||||
this.debounceView(viewport);
|
this.debounceView(viewport);
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +94,6 @@ class FiresMap extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
setShowSubsUnion(show) {
|
setShowSubsUnion(show) {
|
||||||
this.setState({ showSubsUnion: show });
|
|
||||||
this.showSubsUnion(show);
|
this.showSubsUnion(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,28 +127,30 @@ class FiresMap extends React.Component {
|
||||||
|
|
||||||
handleViewportChange(viewport) {
|
handleViewportChange(viewport) {
|
||||||
console.log(`Viewport changed: ${JSON.stringify(viewport)}`);
|
console.log(`Viewport changed: ${JSON.stringify(viewport)}`);
|
||||||
|
if (viewport.center === this.state.viewport.center &&
|
||||||
|
viewport.zoom === this.state.viewport.zoom) {
|
||||||
|
// Do nothing, in same point
|
||||||
|
return;
|
||||||
|
}
|
||||||
zoom.set(viewport.zoom);
|
zoom.set(viewport.zoom);
|
||||||
lat.set(viewport.center[0]);
|
center.set(viewport.center);
|
||||||
lng.set(viewport.center[1]);
|
|
||||||
this.setState({ viewport });
|
this.setState({ viewport });
|
||||||
/* this.state.viewport = viewport;
|
|
||||||
* this.state.modified = true; */
|
|
||||||
if (this.props.subsready && this.fireMap) {
|
if (this.props.subsready && this.fireMap) {
|
||||||
this.showSubsUnion(this.state.showSubsUnion);
|
this.showSubsUnion(this.state.showSubsUnion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
centerOnUserLocation(viewport) {
|
centerOnUserLocation(viewport) {
|
||||||
this.handleViewportChange(viewport);
|
this.setState({ viewport });
|
||||||
|
// this.handleViewportChange(viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
useMarkers(use) {
|
useMarkers(use) {
|
||||||
this.setState({ useMarkers: use });
|
this.setState({ useMarkers: use });
|
||||||
// this.state.useMarkers = use;
|
|
||||||
// this.forceUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addScale() {
|
addScale() {
|
||||||
|
if (this.fireMap) {
|
||||||
// https://www.npmjs.com/package/leaflet-graphicscale
|
// https://www.npmjs.com/package/leaflet-graphicscale
|
||||||
const map = this.getMap();
|
const map = this.getMap();
|
||||||
const options = {
|
const options = {
|
||||||
|
|
@ -145,13 +159,14 @@ class FiresMap extends React.Component {
|
||||||
};
|
};
|
||||||
L.control.graphicScale([options]).addTo(map);
|
L.control.graphicScale([options]).addTo(map);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.subsready && this.fireMap) {
|
if (this.props.subsready && this.fireMap) {
|
||||||
// Show union of users
|
// Show union of users
|
||||||
this.showSubsUnion(this.state.showSubsUnion);
|
this.showSubsUnion(this.state.showSubsUnion);
|
||||||
}
|
}
|
||||||
console.log('Rendering map');
|
console.log(`Rendering ${this.props.loading ? 'loading' : 'LOADED'} map ${this.props.activefires.length} of ${this.props.activefirestotal} total. Subs users ready ${this.props.subsready}, reactive ${this.state.viewport.zoom >= MAXZOOMREACTIVE}`);
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
const osmlayer = (
|
const osmlayer = (
|
||||||
<BaseLayer checked name={t('Mapa gris de OpenStreetMap')}>
|
<BaseLayer checked name={t('Mapa gris de OpenStreetMap')}>
|
||||||
|
|
@ -191,14 +206,22 @@ class FiresMap extends React.Component {
|
||||||
<Trans className="mark-checkbox" parent="span">Resaltar los fuegos con un marcador</Trans>
|
<Trans className="mark-checkbox" parent="span">Resaltar los fuegos con un marcador</Trans>
|
||||||
</Checkbox>}
|
</Checkbox>}
|
||||||
<CenterInMyPosition onClick={viewport => this.centerOnUserLocation(viewport)} />
|
<CenterInMyPosition onClick={viewport => this.centerOnUserLocation(viewport)} />
|
||||||
|
<p>
|
||||||
|
<em>{ this.state.viewport.zoom >= MAXZOOMREACTIVE ?
|
||||||
|
<Trans>Los fuegos activos se actualizan en tiempo real.</Trans> :
|
||||||
|
<Trans>Haga zoom en una zona de su interés si quiere que los fuegos se actualicen en tiempo real.</Trans>
|
||||||
|
}
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
{/* https://github.com/CliffCloud/Leaflet.Sleep */}
|
{/* https://github.com/CliffCloud/Leaflet.Sleep */}
|
||||||
|
|
||||||
<Map
|
<Map
|
||||||
ref={(map) => { this.fireMap = map; }}
|
ref={(map) => { this.fireMap = map; }}
|
||||||
animate
|
animate
|
||||||
// minZoom={4}
|
minZoom={5}
|
||||||
preferCanvas
|
preferCanvas
|
||||||
onClick={this.onClickReset}
|
onClick={this.onClickReset}
|
||||||
viewport={this.state.viewport}
|
viewport={this.state.viewport}
|
||||||
|
|
@ -212,18 +235,20 @@ class FiresMap extends React.Component {
|
||||||
sleepOpacity={0.6}
|
sleepOpacity={0.6}
|
||||||
>
|
>
|
||||||
{/* http://wiki.openstreetmap.org/wiki/Tile_servers */}
|
{/* http://wiki.openstreetmap.org/wiki/Tile_servers */}
|
||||||
|
{!this.props.loading &&
|
||||||
<FireList
|
<FireList
|
||||||
fires={this.props.activefires}
|
fires={this.props.activefires}
|
||||||
scale={this.state.viewport.zoom >= MAXZOOM}
|
scale={this.state.viewport.zoom >= MAXZOOM}
|
||||||
useMarkers={this.state.useMarkers}
|
useMarkers={this.state.useMarkers}
|
||||||
nasa
|
nasa
|
||||||
/>
|
/>}
|
||||||
|
{!this.props.loading &&
|
||||||
<FireList
|
<FireList
|
||||||
fires={this.props.firealerts}
|
fires={this.props.firealerts}
|
||||||
scale={false}
|
scale={false}
|
||||||
useMarkers={this.state.useMarkers}
|
useMarkers={this.state.useMarkers}
|
||||||
nasa={false}
|
nasa={false}
|
||||||
/>
|
/>}
|
||||||
<LayersControl position="topright">
|
<LayersControl position="topright">
|
||||||
{osmlayer}
|
{osmlayer}
|
||||||
{ this.state.gkey &&
|
{ this.state.gkey &&
|
||||||
|
|
@ -261,13 +286,21 @@ FiresMap.propTypes = {
|
||||||
|
|
||||||
export default translate([], { wait: true })(withTracker(() => {
|
export default translate([], { wait: true })(withTracker(() => {
|
||||||
let subscription;
|
let subscription;
|
||||||
|
let init = true;
|
||||||
Meteor.autorun(() => {
|
Meteor.autorun(() => {
|
||||||
if (geolocation.get()) {
|
if (geolocation.get() && init) {
|
||||||
lat.set(geolocation.get()[0]);
|
center.set(geolocation.get());
|
||||||
lng.set(geolocation.get()[1]);
|
init = false;
|
||||||
}
|
}
|
||||||
if (zoom.get() || lat.get() || lng.get()) {
|
if (mapSize.get()) {
|
||||||
subscription = Meteor.subscribe('activefiresmyloc', zoom.get(), lat.get(), lng.get(), height.get(), width.get());
|
subscription = Meteor.subscribe(
|
||||||
|
'activefiresmyloc',
|
||||||
|
zoom.get(),
|
||||||
|
center.get()[0],
|
||||||
|
center.get()[1],
|
||||||
|
mapSize.get()[0],
|
||||||
|
mapSize.get()[1]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -276,18 +309,21 @@ export default translate([], { wait: true })(withTracker(() => {
|
||||||
Meteor.subscribe('fireAlerts');
|
Meteor.subscribe('fireAlerts');
|
||||||
const userSubs = Meteor.subscribe('userSubsToFires');
|
const userSubs = Meteor.subscribe('userSubsToFires');
|
||||||
// const subscription = Meteor.subscribe('activefiresmyloc', zoom.get());
|
// const subscription = Meteor.subscribe('activefiresmyloc', zoom.get());
|
||||||
console.log(`Active fires ${ActiveFiresCollection.find().fetch().length} of ${Counter.get('countActiveFires')}`);
|
// Warning with the performance of this log:
|
||||||
|
// console.log(`Active fires ${ActiveFiresCollection.find().count()} of ${Counter.get('countActiveFires')}`);
|
||||||
// console.log(`Active neighborhood fires ${FireAlertsCollection.find().fetch().length} and users subscribed ${UserSubsToFiresCollection.find().fetch().length}`);
|
// console.log(`Active neighborhood fires ${FireAlertsCollection.find().fetch().length} and users subscribed ${UserSubsToFiresCollection.find().fetch().length}`);
|
||||||
// console.log(UserSubsToFiresCollection.find().fetch());
|
// console.log(UserSubsToFiresCollection.find().fetch());
|
||||||
return {
|
return {
|
||||||
loading: !subscription.ready(),
|
loading: !subscription.ready(),
|
||||||
|
userSubs: UserSubsToFiresCollection.find().fetch(),
|
||||||
subsready: userSubs.ready(),
|
subsready: userSubs.ready(),
|
||||||
activefires: ActiveFiresCollection.find().fetch(),
|
// Not reactive query depending on zoom level
|
||||||
|
activefires: ActiveFiresCollection.find({}, { reactive: zoom.get() >= MAXZOOMREACTIVE }).fetch(),
|
||||||
|
// activefires: ActiveFiresCollection.find({}).fetch(),
|
||||||
activefirestotal: Counter.get('countActiveFires'),
|
activefirestotal: Counter.get('countActiveFires'),
|
||||||
firealerts: FireAlertsCollection.find().fetch().map(doc => (
|
firealerts: FireAlertsCollection.find().fetch().map(doc => (
|
||||||
{ _id: doc._id, lat: doc.location.lat, lon: doc.location.lon }
|
{ _id: doc._id, lat: doc.location.lat, lon: doc.location.lon }
|
||||||
)),
|
)),
|
||||||
userSubs: UserSubsToFiresCollection.find().fetch(),
|
|
||||||
viewport: {
|
viewport: {
|
||||||
center: geolocation.get(),
|
center: geolocation.get(),
|
||||||
zoom: zoom.get()
|
zoom: zoom.get()
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,18 @@
|
||||||
|
/* eslint-disable import/no-absolute-path */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
// import PropTypes from 'prop-types';
|
// import PropTypes from 'prop-types';
|
||||||
import { translate } from 'react-i18next';
|
import { translate } from 'react-i18next';
|
||||||
|
|
||||||
class Sandbox extends React.Component {
|
class Sandbox extends React.Component {
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
/* this.state = {
|
|
||||||
* init: false
|
|
||||||
* }; */
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// this.setState({init: true});
|
// this.setState({init: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div></div>
|
<div>
|
||||||
|
<div />
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -25,4 +21,4 @@ Sandbox.propTypes = {
|
||||||
// history: PropTypes.object.isRequired
|
// history: PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default translate([], { wait: true }) (Sandbox);
|
export default translate([], { wait: true })(Sandbox);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue