<commit_before>import React, {PropTypes, Component} from 'react'
import {GridList} from 'material-ui/GridList'
import DataPackListItem from './DataPackListItem';
import LoadButtons from './LoadButtons';
import MapPopup from './MapPopup';
import CustomScrollbar from '../CustomScrollbar';
import ol from 'openlayers';
import isEqual from 'lodash/isEqual';
import css from '../../styles/ol3map.css';
import Dot from 'material-ui/svg-icons/av/fiber-manual-record';
import SearchAOIToolbar from '../MapTools/SearchAOIToolbar.js';
import DrawAOIToolbar from '../MapTools/DrawAOIToolbar.js';
import InvalidDrawWarning from '../MapTools/InvalidDrawWarning.js';
import DropZone from '../MapTools/DropZone.js';
import {generateDrawLayer, generateDrawBoxInteraction, generateDrawFreeInteraction,
    serialize, isGeoJSONValid, createGeoJSON, createGeoJSONGeometry, zoomToExtent, clearDraw,
    MODE_DRAW_BBOX, MODE_DRAW_FREE, MODE_NORMAL, zoomToGeometry, featureToPoint,
    isViewOutsideValidExtent, goToValidExtent, unwrapCoordinates, unwrapExtent} from '../../utils/mapUtils'

export const RED_STYLE = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: '#ce4427',
        width: 6,
        
    }),
    image: null,
    zIndex: Infinity,
});

export const BLUE_STYLE = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: '#4498c0',
        width: 4,
    }),
    image: null,
    zIndex: 1
});

export class MapView extends Component {
    constructor(props) {
        super(props);
        this.initMap = this.initMap.bind(this);
        this.initOverlay = this.initOverlay.bind(this);
        this.handlePopupClose = this.handlePopupClose.bind(this);
        this.addRunFeatures = this.addRunFeatures.bind(this);
        this.handleClick = this.handleClick.bind(this);
        this.handleOlPopupClose = this.handleOlPopupClose.bind(this);
        this.zoomToSelected = this.zoomToSelected.bind(this);
        this.animate = this.animate.bind(this);
        this.onMapClick = this.onMapClick.bind(this);
        this.setAllButtonsDefault = this.setAllButtonsDefault.bind(this);
        this.setButtonSelected = this.setButtonSelected.bind(this);
        this.toggleImportModal = this.toggleImportModal.bind(this);
        this.showInvalidDrawWarning = this.showInvalidDrawWarning.bind(this);
        this.handleCancel = this.handleCancel.bind(this);
        this.handleSearch = this.handleSearch.bind(this);
        this.onDrawEnd = this.onDrawEnd.bind(this);
        this.onDrawStart = this.onDrawStart.bind(this);
        this.updateMode = this.updateMode.bind(this);
        this.setMapView = this.setMapView.bind(this);
        this.defaultStyleFunction = this.defaultStyleFunction.bind(this);
        this.selectedStyleFunction = this.selectedStyleFunction.bind(this);
        this.state = {
            selectedFeature: null,
            groupedFeatures: [],
            showPopup: false,
            toolbarIcons: {
                box: "DEFAULT",
                free: "DEFAULT",
                mapView: "DEFAULT",
                import: "DEFAULT",
                search: "DEFAULT",
            },
            showImportModal: false,
            showInvalidDrawWarning: false,
            mode: MODE_NORMAL,
            disableMapClick: false,
        }
    }

    componentDidMount() {
        this.map = this.initMap();
        this.initOverlay();
        this.source = new ol.source.Vector({wrapX: true});
        this.layer = new ol.layer.Vector({
            source: this.source,
            style: this.defaultStyleFunction
        });
        this.drawLayer = generateDrawLayer();

        this.drawBoxInteraction = generateDrawBoxInteraction(this.drawLayer);
        this.drawBoxInteraction.on('drawstart', this.onDrawStart);
        this.drawBoxInteraction.on('drawend', this.onDrawEnd);

        this.drawFreeInteraction = generateDrawFreeInteraction(this.drawLayer);
        this.drawFreeInteraction.on('drawstart', this.onDrawStart);
        this.drawFreeInteraction.on('drawend', this.onDrawEnd);

        this.map.addInteraction(this.drawBoxInteraction);
        this.map.addInteraction(this.drawFreeInteraction);
        

        this.map.addLayer(this.layer);
        this.map.addLayer(this.drawLayer);

        this.addRunFeatures(this.props.runs, this.source);
        this.map.getView().fit(this.source.getExtent(), this.map.getSize());
        this.clickListener = this.map.on('singleclick', this.onMapClick);
    }

    componentWillReceiveProps(nextProps) {
        // if the runs have changed, clear out old features and re-add with new features
        if (this.hasNewRuns(this.props.runs, nextProps.runs)) {
            this.source.clear();
            const added = this.addRunFeatures(nextProps.runs, this.source);
            const drawExtent = this.drawLayer.getSource().getExtent();
            const runsExtent = this.source.getExtent();
            // if any features were added to the source
            if (added) {
                // if there is a draw feature and it contains all the runs: fit to draw feature
                if (this.drawLayer.getSource().getFeatures().length && ol.extent.containsExtent(drawExtent, runsExtent)) {
                        this.map.getView().fit(drawExtent);
                }
                // if no draw feature or it does not contain all runs: just fit the runs
                else {
                    this.map.getView().fit(runsExtent);
                }
            }
            // if no features added but there is a draw feature: zoom to draw feature
            else if (this.drawLayer.getSource().getFeatures().length) {
                zoomToGeometry(this.drawLayer.getSource().getFeatures()[0].getGeometry(), this.map);
            }
        }

        if(nextProps.importGeom.processed && !this.props.importGeom.processed) {
            this.handleGeoJSONUpload(nextProps.importGeom.geom);
        }
    }

    // update map size so it doesnt look like crap after page resize
    componentDidUpdate() {
        this.map.updateSize();
    }

    hasNewRuns(prevRuns, nextRuns) {
        if (prevRuns.length != nextRuns.length) {
            return true;
        }
        else {
            for (let i=0; i < nextRuns.length; i++) {
                if (nextRuns[i].uid != prevRuns[i].uid) {
                    return true;
                }
            };
            return false
        }
    }

    // read the extents from the runs and add each feature to the source
    addRunFeatures(runs, source) {
        const reader = new ol.format.GeoJSON();
        const features = runs.map((run) => { 
            let feature = reader.readFeature(run.job.extent, {
                dataProjection: 'EPSG:4326',
                featureProjection: 'EPSG:3857'
            });
            feature.setId(run.uid);
            feature.setProperties(run);
            return feature;
        });
        if (features.length) {
            source.addFeatures(features);
            return true;
        };
        return false;
    }

    // add map with controls and basemap to the page
    initMap() {
        ol.control.ZoomExtent = zoomToExtent;
        ol.inherits(ol.control.ZoomExtent, ol.control.Control);
        return new ol.Map({
            controls: [
                new ol.control.Attribution({
                    className: ['ol-attribution', css['ol-attribution']].join(' '),
                    collapsible: false,
                    collapsed: false,
                }),
                new ol.control.Zoom({
                    className: css.olZoom
                }),
                new ol.control.ZoomExtent({
                    className: css.olZoomToExtent,
                    extent: [-14251567.50789682, -10584983.780136958, 14251787.50789682, 10584983.780136958],
                }),
                new ol.control.OverviewMap({
                    className: ['ol-overviewmap', css['ol-custom-overviewmap']].join(' '),
                    collapsible: true,
                    collapsed: window.innerWidth < 768 ? true: false,
                }),
            ],
            interactions: ol.interaction.defaults({
                keyboard: false,
                altShiftDragRotate: false,
                pinchRotate: false
            }),
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: this.context.config.BASEMAP_URL,
                        wrapX: true,
                        attributions: this.context.config.BASEMAP_COPYRIGHT
                    })
                }),
            ],
            target: 'map',
            view: new ol.View({
                projection: "EPSG:3857",
                center: [110, 0],
                zoom: 2,
                minZoom: 2,
                maxZoom: 22,
            })
        });
    }
<commit_msg>Flip backwards chevrons for showing/hiding map overview.<commit_after>import React, {PropTypes, Component} from 'react'
import {GridList} from 'material-ui/GridList'
import DataPackListItem from './DataPackListItem';
import LoadButtons from './LoadButtons';
import MapPopup from './MapPopup';
import CustomScrollbar from '../CustomScrollbar';
import ol from 'openlayers';
import isEqual from 'lodash/isEqual';
import css from '../../styles/ol3map.css';
import Dot from 'material-ui/svg-icons/av/fiber-manual-record';
import SearchAOIToolbar from '../MapTools/SearchAOIToolbar.js';
import DrawAOIToolbar from '../MapTools/DrawAOIToolbar.js';
import InvalidDrawWarning from '../MapTools/InvalidDrawWarning.js';
import DropZone from '../MapTools/DropZone.js';
import {generateDrawLayer, generateDrawBoxInteraction, generateDrawFreeInteraction,
    serialize, isGeoJSONValid, createGeoJSON, createGeoJSONGeometry, zoomToExtent, clearDraw,
    MODE_DRAW_BBOX, MODE_DRAW_FREE, MODE_NORMAL, zoomToGeometry, featureToPoint,
    isViewOutsideValidExtent, goToValidExtent, unwrapCoordinates, unwrapExtent} from '../../utils/mapUtils'

export const RED_STYLE = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: '#ce4427',
        width: 6,
        
    }),
    image: null,
    zIndex: Infinity,
});

export const BLUE_STYLE = new ol.style.Style({
    stroke: new ol.style.Stroke({
        color: '#4498c0',
        width: 4,
    }),
    image: null,
    zIndex: 1
});

export class MapView extends Component {
    constructor(props) {
        super(props);
        this.initMap = this.initMap.bind(this);
        this.initOverlay = this.initOverlay.bind(this);
        this.handlePopupClose = this.handlePopupClose.bind(this);
        this.addRunFeatures = this.addRunFeatures.bind(this);
        this.handleClick = this.handleClick.bind(this);
        this.handleOlPopupClose = this.handleOlPopupClose.bind(this);
        this.zoomToSelected = this.zoomToSelected.bind(this);
        this.animate = this.animate.bind(this);
        this.onMapClick = this.onMapClick.bind(this);
        this.setAllButtonsDefault = this.setAllButtonsDefault.bind(this);
        this.setButtonSelected = this.setButtonSelected.bind(this);
        this.toggleImportModal = this.toggleImportModal.bind(this);
        this.showInvalidDrawWarning = this.showInvalidDrawWarning.bind(this);
        this.handleCancel = this.handleCancel.bind(this);
        this.handleSearch = this.handleSearch.bind(this);
        this.onDrawEnd = this.onDrawEnd.bind(this);
        this.onDrawStart = this.onDrawStart.bind(this);
        this.updateMode = this.updateMode.bind(this);
        this.setMapView = this.setMapView.bind(this);
        this.defaultStyleFunction = this.defaultStyleFunction.bind(this);
        this.selectedStyleFunction = this.selectedStyleFunction.bind(this);
        this.state = {
            selectedFeature: null,
            groupedFeatures: [],
            showPopup: false,
            toolbarIcons: {
                box: "DEFAULT",
                free: "DEFAULT",
                mapView: "DEFAULT",
                import: "DEFAULT",
                search: "DEFAULT",
            },
            showImportModal: false,
            showInvalidDrawWarning: false,
            mode: MODE_NORMAL,
            disableMapClick: false,
        }
    }

    componentDidMount() {
        this.map = this.initMap();
        this.initOverlay();
        this.source = new ol.source.Vector({wrapX: true});
        this.layer = new ol.layer.Vector({
            source: this.source,
            style: this.defaultStyleFunction
        });
        this.drawLayer = generateDrawLayer();

        this.drawBoxInteraction = generateDrawBoxInteraction(this.drawLayer);
        this.drawBoxInteraction.on('drawstart', this.onDrawStart);
        this.drawBoxInteraction.on('drawend', this.onDrawEnd);

        this.drawFreeInteraction = generateDrawFreeInteraction(this.drawLayer);
        this.drawFreeInteraction.on('drawstart', this.onDrawStart);
        this.drawFreeInteraction.on('drawend', this.onDrawEnd);

        this.map.addInteraction(this.drawBoxInteraction);
        this.map.addInteraction(this.drawFreeInteraction);
        

        this.map.addLayer(this.layer);
        this.map.addLayer(this.drawLayer);

        this.addRunFeatures(this.props.runs, this.source);
        this.map.getView().fit(this.source.getExtent(), this.map.getSize());
        this.clickListener = this.map.on('singleclick', this.onMapClick);
    }

    componentWillReceiveProps(nextProps) {
        // if the runs have changed, clear out old features and re-add with new features
        if (this.hasNewRuns(this.props.runs, nextProps.runs)) {
            this.source.clear();
            const added = this.addRunFeatures(nextProps.runs, this.source);
            const drawExtent = this.drawLayer.getSource().getExtent();
            const runsExtent = this.source.getExtent();
            // if any features were added to the source
            if (added) {
                // if there is a draw feature and it contains all the runs: fit to draw feature
                if (this.drawLayer.getSource().getFeatures().length && ol.extent.containsExtent(drawExtent, runsExtent)) {
                        this.map.getView().fit(drawExtent);
                }
                // if no draw feature or it does not contain all runs: just fit the runs
                else {
                    this.map.getView().fit(runsExtent);
                }
            }
            // if no features added but there is a draw feature: zoom to draw feature
            else if (this.drawLayer.getSource().getFeatures().length) {
                zoomToGeometry(this.drawLayer.getSource().getFeatures()[0].getGeometry(), this.map);
            }
        }

        if(nextProps.importGeom.processed && !this.props.importGeom.processed) {
            this.handleGeoJSONUpload(nextProps.importGeom.geom);
        }
    }

    // update map size so it doesnt look like crap after page resize
    componentDidUpdate() {
        this.map.updateSize();
    }

    hasNewRuns(prevRuns, nextRuns) {
        if (prevRuns.length != nextRuns.length) {
            return true;
        }
        else {
            for (let i=0; i < nextRuns.length; i++) {
                if (nextRuns[i].uid != prevRuns[i].uid) {
                    return true;
                }
            };
            return false
        }
    }

    // read the extents from the runs and add each feature to the source
    addRunFeatures(runs, source) {
        const reader = new ol.format.GeoJSON();
        const features = runs.map((run) => { 
            let feature = reader.readFeature(run.job.extent, {
                dataProjection: 'EPSG:4326',
                featureProjection: 'EPSG:3857'
            });
            feature.setId(run.uid);
            feature.setProperties(run);
            return feature;
        });
        if (features.length) {
            source.addFeatures(features);
            return true;
        };
        return false;
    }

    // add map with controls and basemap to the page
    initMap() {
        ol.control.ZoomExtent = zoomToExtent;
        ol.inherits(ol.control.ZoomExtent, ol.control.Control);
        return new ol.Map({
            controls: [
                new ol.control.Attribution({
                    className: ['ol-attribution', css['ol-attribution']].join(' '),
                    collapsible: false,
                    collapsed: false,
                }),
                new ol.control.Zoom({
                    className: css.olZoom
                }),
                new ol.control.ZoomExtent({
                    className: css.olZoomToExtent,
                    extent: [-14251567.50789682, -10584983.780136958, 14251787.50789682, 10584983.780136958],
                }),
                new ol.control.OverviewMap({
                    className: ['ol-overviewmap', css['ol-custom-overviewmap']].join(' '),
                    collapsible: true,
                    collapsed: window.innerWidth < 768 ? true: false,
                    collapseLabel: '\u00BB',
                    label: '\u00AB',
                }),
            ],
            interactions: ol.interaction.defaults({
                keyboard: false,
                altShiftDragRotate: false,
                pinchRotate: false
            }),
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: this.context.config.BASEMAP_URL,
                        wrapX: true,
                        attributions: this.context.config.BASEMAP_COPYRIGHT
                    })
                }),
            ],
            target: 'map',
            view: new ol.View({
                projection: "EPSG:3857",
                center: [110, 0],
                zoom: 2,
                minZoom: 2,
                maxZoom: 22,
            })
        });
    }

{'fraction_non_alphanumeric': 0.1102863202545069, 'fraction_numerical': 0.011832338003013898, 'mean_word_length': 1.9621425028930402, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 2, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2653311', 'n_tokens_mistral': 5178, 'n_tokens_neox': 4915, 'n_words': 984}