import React from 'react'; import PropTypes from 'prop-types'; import AssetDownloads from '../classes/AssetDownloads'; import '../css/GCPPopup.scss'; import { _ } from '../classes/gettext'; class GCPPopup extends React.Component { static propTypes = { feature: PropTypes.object.isRequired, task: PropTypes.object.isRequired, }; constructor(props){ super(props); this.state = { error: "", loading: true, expandGCPImage: false, selectedShot: "", zoom: 4 } } selectShot = (shotId) => { if (shotId !== this.state.selectedShot){ this.setState({loading: true, selectedShot: shotId, error: ""}); } } _getCoords = (shotId, key) => { if (!shotId) return [0.5, 0.5]; const { feature } = this.props; const ob = feature.properties.observations.find(o => o.shot_id === shotId); if (ob){ return ob[key]; }else{ return [0.5, 0.5]; } } getAnnotationCoords = (shotId) => { return this._getCoords(shotId, 'annotated'); } getReprojectedCoords = (shotId) => { return this._getCoords(shotId, 'reprojected'); } getThumbUrl = (size) => { const { task } = this.props; const { selectedShot, zoom } = this.state; const annotated = this.getAnnotationCoords(selectedShot); const reprojected = this.getReprojectedCoords(selectedShot); return `/api/projects/${task.project}/tasks/${task.id}/images/thumbnail/${selectedShot}?size=${size}¢er_x=${annotated[0]}¢er_y=${annotated[1]}&draw_point=${annotated[0]},${annotated[1]}&point_color=f29900&point_radius=2&draw_point=${reprojected[0]},${reprojected[1]}&&point_color=00ff00&point_radius=2&zoom=${zoom}`; } componentDidMount(){ const { feature } = this.props; document.addEventListener("fullscreenchange", this.onFullscreenChange); if (feature.properties.observations) this.selectShot(feature.properties.observations[0].shot_id); if (this.imageContainer) this.imageContainer.addEventListener("mousewheel", this.onImageWheel); // onWheel doesn't work :/ } componentWillUnmount(){ document.removeEventListener("fullscreenchange", this.onFullscreenChange); if (this.imageContainer) this.imageContainer.removeEventListener("mousewheel", this.onImageWheel); } onFullscreenChange = (e) => { if (!document.fullscreenElement){ this.setState({expandGCPImage: false}); } } imageOnError = () => { this.setState({error: _("Image missing"), loading: false}); } imageOnLoad = () => { this.setState({loading: false}); } canZoomIn = () => { return this.state.zoom < 10 && !this.state.loading; } canZoomOut = () => { return this.state.zoom > 1 && !this.state.loading; } zoomIn = () => { if (this.canZoomIn()){ this.setState({loading: true, zoom: this.state.zoom + 1}); } } zoomOut = () => { if (this.canZoomOut()){ this.setState({loading: true, zoom: this.state.zoom - 1}); } } onImageWheel = e => { if (e.deltaY > 0){ this.zoomIn(); }else{ this.zoomOut(); } } onImgClick = () => { const { expandGCPImage } = this.state; if (!expandGCPImage){ this.image.requestFullscreen(); this.setState({ loading: true, expandGCPImage: true}); }else{ document.exitFullscreen(); this.setState({ loading: true, expandGCPImage: false }); } } render(){ const { error, loading, expandGCPImage, selectedShot } = this.state; const { feature, task } = this.props; const downloadGCPLink = `/api/projects/${task.project}/tasks/${task.id}/download/ground_control_points.geojson`; const assetDownload = AssetDownloads.only(["ground_control_points.geojson"])[0]; const imageUrl = expandGCPImage ? this.getThumbUrl(999999999) : this.getThumbUrl(320); const shotLinks = []; for (let i = 0; i < feature.properties.observations.length; i++){ const obs = feature.properties.observations[i]; if (obs.shot_id === selectedShot){ shotLinks.push({obs.shot_id}); }else{ shotLinks.push( this.selectShot(obs.shot_id)}>{obs.shot_id}); } if (i+1 < feature.properties.observations.length) shotLinks.push( | ); } const imgStyle = { borderRadius: "4px", minHeight: "32px" }; return (
{feature.properties.id}
{shotLinks}
this.imageContainer = domNode }> {loading ?
: ""} {error ?
{error}
: ""} {!error && selectedShot !== "" ?
{ this.image = domNode;}}> {loading && expandGCPImage ?
: ""}
: ""}
{_("Horizontal error:")} {Math.abs(Math.max(feature.properties.error[0], feature.properties.error[1])).toFixed(3)} {_("(meters)")}
{_("Vertical error:")} {Math.abs(feature.properties.error[2]).toFixed(3)} {_("(meters)")}
{assetDownload.label}
); } } export default GCPPopup;