UNPKG

terriajs

Version:

Geospatial data visualization platform.

174 lines (154 loc) 5.47 kB
import createReactClass from "create-react-class"; import PropTypes from "prop-types"; import React from "react"; import defined from "terriajs-cesium/Source/Core/defined"; import Ellipsoid from "terriajs-cesium/Source/Core/Ellipsoid"; import Rectangle from "terriajs-cesium/Source/Core/Rectangle"; import MapInteractionMode from "../../../Models/MapInteractionMode"; import Loader from "../../Loader"; import LocationItem from "../../LocationItem.jsx"; import { withTranslation } from "react-i18next"; import { observer } from "mobx-react"; import { runInAction, reaction } from "mobx"; import Styles from "./satellite-imagery-time-filter-section.scss"; const SatelliteImageryTimeFilterSection = observer( createReactClass({ displayName: "SatelliteImageryTimeFilterSection", propTypes: { item: PropTypes.object, t: PropTypes.func.isRequired }, removeFilter() { this.props.item.removeTimeFilterFeature(); }, zoomTo() { const feature = this.props.item.timeFilterFeature; const position = feature !== undefined && feature.position !== undefined ? feature.position.getValue(this.props.item.currentTime) : undefined; if (defined(position)) { const cartographic = Ellipsoid.WGS84.cartesianToCartographic(position); this.props.item.terria.currentViewer.zoomTo( new Rectangle( cartographic.longitude - 0.0005, cartographic.latitude - 0.0005, cartographic.longitude + 0.0005, cartographic.latitude + 0.0005 ) ); } }, newLocation() { const { t } = this.props; // Cancel any feature picking already in progress. const terria = this.props.item.terria; const pickPointMode = new MapInteractionMode({ message: t("satellite.pickPoint"), onCancel: () => runInAction(() => terria.mapInteractionModeStack.pop()) }); runInAction(() => terria.mapInteractionModeStack.push(pickPointMode)); // Set up a reaction to observe pickedFeatures and filter the items // discrete times const disposer = reaction( () => pickPointMode.pickedFeatures, async (pickedFeatures) => { runInAction(() => { pickPointMode.customUi = function () { return <Loader message={t("satellite.querying")} />; }; }); await pickedFeatures.allFeaturesAvailablePromise; if ( terria.mapInteractionModeStack[ terria.mapInteractionModeStack.length - 1 ] !== pickPointMode ) { // already cancelled disposer(); return; } const item = this.props.item; const thisLayerFeature = pickedFeatures.features.filter((feature) => { return ( item.mapItems.find( (mapItem) => mapItem.imageryProvider && mapItem.imageryProvider === feature.imageryLayer?.imageryProvider ) !== undefined ); })[0]; if (thisLayerFeature !== undefined) { try { item.setTimeFilterFeature( thisLayerFeature, pickedFeatures.providerCoords ); } catch (e) { terria.raiseErrorToUser(e); } } runInAction(() => terria.mapInteractionModeStack.pop()); disposer(); } ); }, render() { if (!this.props.item.canFilterTimeByFeature) { return null; } const feature = this.props.item.timeFilterFeature; if (feature === undefined) { return this.renderNoFeatureSelected(); } else { return this.renderFeatureSelected(feature); } }, renderNoFeatureSelected() { const { t } = this.props; return ( <div className={Styles.inactive}> <div className={Styles.btnGroup}> <button className={Styles.btn} onClick={this.newLocation}> {t("satellite.filterByLocation")} </button> </div> </div> ); }, renderFeatureSelected(feature) { const { t } = this.props; // TODO: if the feature itself doesn't have a position, we should be able to use the position the user clicked on. const position = feature.position !== undefined ? feature.position.getValue(this.props.item.currentTime) : undefined; return ( <div className={Styles.active} css={` background: ${(p) => p.theme.colorPrimary}; `} > <div className={Styles.infoGroup}> <div>{t("satellite.infoGroup")}</div> <LocationItem position={position} /> </div> <div className={Styles.btnGroup}> <button className={Styles.btn} onClick={this.removeFilter}> {t("satellite.removeFilter")} </button> <button className={Styles.btn} onClick={this.zoomTo}> {t("satellite.zoomTo")} </button> <button className={Styles.btn} onClick={this.newLocation}> {t("satellite.newLocation")} </button> </div> </div> ); } }) ); export default withTranslation()(SatelliteImageryTimeFilterSection);