UNPKG

naksha-react-ui

Version:

Visualize grid heat map or layer map from elastic search or https://github.com/strandls/naksha

192 lines (165 loc) 5 kB
import React, { Component } from 'react'; import Map from './Map'; import Geohash from './geohash/geohash-geojson' import GeohashAggr from './geohash/geohash-aggregated-geojson' import LegendStops from './legend-stops' import axios from 'axios'; import mapboxgl from 'mapbox-gl'; mapboxgl.accessToken = 'undefined'; class MapData extends Component { constructor(props) { super(props); let bounds = this.props.map.getBounds(); this.state = { data: undefined, stops: [], area: undefined, zoom: this.props.default_zoom, top: bounds._ne.lat, right: bounds._ne.lng, left: bounds._sw.lng, bottom: bounds._sw.lat } this.props.map.setZoom(this.state.zoom); this.initZoomHandler(); this.initDragHandler(); }; initZoomHandler() { this.props.map.on('zoom', () => { let zoom = this.props.map.getZoom().toFixed(0); if (zoom !== this.state.zoom) { this.setState({ zoom: zoom }) let bounds = this.setBounds(); this.setData(zoom, bounds, false); } }); } initDragHandler() { this.props.map.on('drag', (e) => { let bounds = this.getMapBounds(); if (bounds.bottom < this.state.bottom || bounds.top > this.state.top || bounds.left < this.state.left || bounds.right > this.state.right) { let bounds = this.setBounds(); this.setData(this.state.zoom, bounds, true); } }); } getMapBounds() { let bounds = this.props.map.getBounds(); let top = bounds._ne.lat; let right = bounds._ne.lng; let left = bounds._sw.lng; let bottom = bounds._sw.lat; return {top: top, left: left, bottom: bottom, right: right}; } setBounds() { let bounds = this.getMapBounds(); let top = bounds.top; let right = bounds.right; let left = bounds.left; let bottom = bounds.bottom; let latDiff = top - bottom; let lngDiff = right - left; top = Math.min(top + latDiff, 90); left = Math.max(left - lngDiff, -180); bottom = Math.max(bottom - latDiff, -90); right = Math.min(right + lngDiff, 180); this.setState({ top: top, left: left, bottom: bottom, right: right }); return [top, left, bottom, right] } getPrecisionAndLevelForZoom(zoom) { if(!zoom) zoom = this.state.zoom; if(zoom < 6) return [4, 1, 39.2] else if(zoom < 7) return [5, 0, 19.6] else if(zoom < 8) return [5, 1, 9.8] else if(zoom < 9) return [5, -1, 4.9] else if(zoom < 10) return [6, 0, 2.45] else if(zoom < 11) return [6, 1, 1.225] else if(zoom < 12) return [7, 0, 0.612] else if(zoom < 13) return [7, 1, 0.306] else if(zoom < 14) return [7, -1, 0.153] else if(zoom < 15) return [8, 0, 0.077]; return [8, 1, 0.039]; } setData(zoom, bounds, onlyFilteredAggregation) { let [precision, level, squareSide] = this.getPrecisionAndLevelForZoom(zoom); axios .get(this.props.url, { params: { geoAggregationField: this.props.location_field, geoAggegationPrecision: precision, top: bounds[0], left: bounds[1], bottom: bounds[2], right: bounds[3], onlyFilteredAggregation: onlyFilteredAggregation } }) .then(({ data }) => { this.updateData(data, level); if(!onlyFilteredAggregation) this.updateStops(data, level, squareSide); }) .catch((err) => { console.log('error ' + err); }) } updateData(data, level) { data = this.props.url_response_filtered_geohash_field ? data[this.props.url_response_filtered_geohash_field] : data; data = JSON.parse(data); data = data[Object.keys(data)[0]].buckets; let geojson = level === -1 ? Geohash(data) : GeohashAggr(data, level); this.setState({ data: geojson.geojson }); } updateStops(data, level, squareSide) { data = this.props.url_response_geohash_field ? data[this.props.url_response_geohash_field] : data; data = JSON.parse(data); data = data[Object.keys(data)[0]].buckets; let geojson = level === -1 ? Geohash(data) : GeohashAggr(data, level); let stops = LegendStops(this.props.color_scheme, this.props.is_legend_stops_data_driven, this.props.no_legend_stops, geojson.counts); let area = squareSide + "*" + squareSide + " km" this.setState({ stops: stops, area: area }); } componentDidMount() { this.setData(this.state.zoom, [this.state.top, this.state.left, this.state.bottom, this.state.right], false); } render() { return ( <div> <Map map = {this.props.map} on_click = {this.props.on_click} data = {this.state.data} stops = {this.state.stops} area = {this.state.area} /> </div> ) } } export default MapData;