Skip to content
Snippets Groups Projects
olHelpers_mapPopupCls.js.html 21.5 KiB
Newer Older
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: olHelpers/mapPopupCls.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: olHelpers/mapPopupCls.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 * Created by gavorhes on 11/3/2015.
 */

Glenn Vorhes's avatar
Glenn Vorhes committed
import $ from '../jquery/jquery';
import MapInteractionBase from './mapInteractionBase';
import propertiesZoomStyle from '../olHelpers/propertiesZoomStyle';
import provide from '../util/provide';
Glenn Vorhes's avatar
Glenn Vorhes committed
import ol from '../ol/ol';


Glenn Vorhes's avatar
Glenn Vorhes committed
const nm = provide('olHelpers');


class _FeatureLayerProperties {

    /**
     *
     * @param {ol.Feature} feature the feature
     * @param {LayerBaseVector|*} layer - the layer in the popup
     * @param {number} layerIndex - index of the layer
     * @param {ol.layer.Vector} selectionLayer - the ol selection layer
     * @param {string} [esriLayerName=undefined] - esri layer name
     */
    constructor(feature, layer, layerIndex, selectionLayer, esriLayerName) {
        this.feature = feature;
        this.layer = layer;
        this.layerIndex = layerIndex;
        this.selectionLayer = selectionLayer;
        this.popupContent = '';
        this.esriLayerName = typeof esriLayerName == 'string' ? esriLayerName : undefined;
    }

    get layerName() {
        if (typeof this.esriLayerName == 'string') {
            return this.esriLayerName;
        } else {
            return this.layer.name;
        }
    }
}

/**
 * map popup class
 * @augments MapInteractionBase
 */
class MapPopupCls extends MapInteractionBase {

    /**
     * Definition for openlayers style function
     * @callback olStyleFunction
     * &amp;param feature the openlayers vector feature
     * $param
     */

    /**
     * Definition for popup changed callback functions
     * @callback popupChangedFunction
     * @param $popContent jquery reference to the popup content
     */

    /**
     * map popup constructor
     */
    constructor() {
        super('map popup');
        this._arrPopupLayerIds = [];
        this._arrPopupLayerNames = [];
        /**
         *
         * @type {Array&lt;LayerBaseVector>}
         * @private
         */
        this._arrPopupLayers = [];
        this._arrPopupOlLayers = [];
        this._arrPopupContentFunction = [];
        this._$popupContainer = undefined;
        this._$popupContent = undefined;
        this._$popupCloser = undefined;
        this._popupOverlay = undefined;
        this._selectionLayers = [];
        this._selectionLayerLookup = {};
        this._mapClickFunctions = [];

        //let a = function($jqueryContent){console.log($jqueryContent)};
        //this._popupChangedLookup = {'a': a};
        this._popupChangedFunctions = [];
        /**
         *
         * @type {Array&lt;LayerEsriMapServer>}
         * @private
         */
        this._esriMapServiceLayers = [];

        this._popupOpen = false;
        this._popupCoordinate = null;

        /**
         *
         * @type {Array.&lt;_FeatureLayerProperties>}
         */
        this._passThroughLayerFeatureArray = [];

        this._currentPopupIndex = -1;
        this._popupContentLength = 0;

    }

    /**
     * map popup initialization
     * @param {ol.Map} theMap - the ol map
     */
    init(theMap) {
        if (super.init(theMap)) {
            return;
        }
        let $map = $('#' + this.map.getTarget());

        $map.append(
            '&lt;div class="ol-popup">' +
Glenn Vorhes's avatar
Glenn Vorhes committed
            '&lt;span class="ol-popup-closer">X&lt;/span>' +
            '&lt;div class="popup-content">&lt;/div>' +
            '&lt;/div>'
        );

        this._$popupContainer = $map.find('.ol-popup');
        this._$popupContent = $map.find('.popup-content');
        this._$popupCloser = $map.find('.ol-popup-closer');

        this._popupOverlay = new ol.Overlay({
            element: this._$popupContainer[0],
            autoPan: true,
            autoPanAnimation: {
                duration: 250
            }
        });

        this._map.addOverlay(this._popupOverlay);

Glenn Vorhes's avatar
Glenn Vorhes committed
        this._$popupCloser.click((evt) => {
            this.closePopup();
        });

        // display popup on click
        this._map.on('singleclick', (evt) => {
            this.closePopup();
            this._popupCoordinate = evt.coordinate;

            if (this._esriMapServiceLayers.length > 0) {
                let queryParams = {
                    geometry: evt.coordinate.join(','),
                    geometryType: 'esriGeometryPoint',
                    layers: 'all',
                    sr: this._map.getView().getProjection().getCode().split(':')[1],
                    mapExtent: this._map.getView().calculateExtent(this._map.getSize()).join(','),
                    imageDisplay: this._map.getSize().join(',') + ',96',
                    returnGeometry: true,
                    tolerance: 15,
                    f: 'pjson'
                };

                for (let l of this._esriMapServiceLayers) {
                    l.getPopupInfo(queryParams, this._selectionLayerLookup[l.id]);
                }
            }

            let layerFeatureObjectArray = this._featuresAtPixel(evt.pixel);

            /**
             *
             * @type {Array.&lt;_FeatureLayerProperties>}
             */
            this._passThroughLayerFeatureArray = [];
            this._currentPopupIndex = -1;

            for (let i = 0; i &lt; layerFeatureObjectArray.length; i++) {
                let featObj = layerFeatureObjectArray[i];

                let props = featObj.feature.getProperties();

                let popupContentResponse = this._arrPopupContentFunction[featObj.layerIndex](props, this._$popupContent);

                //skip if return was false
                if (popupContentResponse === false) {
                    //continue;
                } else if (typeof popupContentResponse == 'string') {
                    featObj.popupContent = popupContentResponse;
                    this._passThroughLayerFeatureArray.push(featObj);
                } else {
                    featObj.selectionLayer.getSource().addFeature(featObj.feature);
                }
            }

            this._popupContentLength = this._passThroughLayerFeatureArray.length;

            this._currentPopupIndex = -1;

            let popupHtml = '&lt;div class="ol-popup-nav">';
            popupHtml += '&lt;span class="previous-popup ol-popup-nav-arrow">&amp;#9664;&lt;/span>';
            popupHtml += '&lt;span class="next-popup ol-popup-nav-arrow">&amp;#9654;&lt;/span>';
            popupHtml += `&lt;span class="current-popup-item-number" style="font-weight: bold;">&lt;/span>`;
            popupHtml += `&lt;span>&amp;nbsp;of&amp;nbsp;&lt;/span>`;
            popupHtml += `&lt;span class="popup-content-length" style="font-weight: bold;">${this._popupContentLength}&lt;/span>`;
            popupHtml += `&lt;span>&amp;nbsp;&amp;nbsp;-&amp;nbsp;&amp;nbsp;&lt;/span>`;
            popupHtml += `&lt;span class="current-popup-layer-name">&lt;/span>`;
            popupHtml += '&lt;/div>';
            popupHtml += '&lt;div class="ol-popup-inner">';

            popupHtml += '&lt;/div>';

            this._$popupContent.html(popupHtml);

            this._$popupContent.find('.previous-popup').click(() => {
                if (this._popupContentLength == 1) {
                    return;
                }

                if (this._currentPopupIndex == 0) {
                    this._currentPopupIndex = this._popupContentLength - 1;
                } else {
                    this._currentPopupIndex--;
                }
                this._triggerFeatSelect();
            });

            let nextPopup = this._$popupContent.find('.next-popup');

            nextPopup.click(() => {
                if (this._popupContentLength == 1 &amp;&amp; this._currentPopupIndex > -1) {
                    return;
                }

                if (this._currentPopupIndex == this._popupContentLength - 1) {
                    this._currentPopupIndex = 0;
                } else {
                    this._currentPopupIndex++;
                }
                this._triggerFeatSelect();
            });


            if (this._popupContentLength > 0) {
                nextPopup.trigger('click');
                this._popupOverlay.setPosition(this._popupCoordinate);
                this._$popupContent.scrollTop(0);
                this._popupOpen = true;
            }
        });

        //change mouse cursor when over marker
        this._map.on('pointermove', (e) => {
            if (e.dragging) {
                return;
            }
            let pixel = this.map.getEventPixel(e.originalEvent);
            let hit = this.map.hasFeatureAtPixel(pixel, (lyrCandidate) => {
                for (let olLayer of this._arrPopupOlLayers) {
                    if (lyrCandidate == olLayer) {
                        return true;
                    }
                }

                return false;
            });
            this.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
        });
    }

    /**
     * helper to select features
     * @private
     */
    _triggerFeatSelect() {
        let $currentPopupItemNumber = this._$popupContent.find('.current-popup-item-number');
        let $innerPopup = this._$popupContent.find('.ol-popup-inner');
        let $layerNameSpan = this._$popupContent.find('.current-popup-layer-name');
        this.clearSelection();
        let lyrFeatObj = this._passThroughLayerFeatureArray[this._currentPopupIndex];
        $currentPopupItemNumber.html((this._currentPopupIndex + 1).toFixed());
        $layerNameSpan.html(lyrFeatObj.layerName);
        $innerPopup.html(lyrFeatObj.popupContent);
        lyrFeatObj.selectionLayer.getSource().addFeature(lyrFeatObj.feature);
        for (let f of this._popupChangedFunctions) {
            f(this._$popupContent);
        }
    }


    /**
     *
     * @param {ol.Feature} feature - the ol feature
     * @param {LayerEsriMapServer} lyr - the map server layer
     * @param {string} popupContent - popup content
     * @param {string} esriName - esri layer name
     */
    addMapServicePopupContent(feature, lyr, popupContent, esriName) {

        let featLayerObject = new _FeatureLayerProperties(
            feature, lyr, this._popupContentLength, this._selectionLayerLookup[lyr.id], esriName
        );
        featLayerObject.popupContent = popupContent;

        this._passThroughLayerFeatureArray.push(featLayerObject);
        this._popupContentLength++;

        $('.popup-content-length').html(this._popupContentLength.toFixed());

        if (!this._popupOpen) {
            this._$popupContent.find('.next-popup').trigger('click');

            this._popupOverlay.setPosition(this._popupCoordinate);
            this._$popupContent.scrollTop(0);
            this._popupOpen = true;
        }
    }

    /**
     *
     * @param {ol.Pixel} pixel - the ol pixel
     * @returns {Array.&lt;_FeatureLayerProperties>} - feature layer properties
     * @private
     */
    _featuresAtPixel(pixel) {
        let layerFeatureObjectArray = [];
        this.map.forEachFeatureAtPixel(pixel, (feature, layer) => {
            let lyrIndex = this._arrPopupOlLayers.indexOf(layer);

            if (lyrIndex > -1) {
                layerFeatureObjectArray.push(new _FeatureLayerProperties(
                    feature, this._arrPopupLayers[lyrIndex], lyrIndex, this._selectionLayers[lyrIndex]));
            }
        });

        return layerFeatureObjectArray;
    }

    closePopup() {
        this._checkInit();
        this._popupOpen = false;
        this._popupOverlay.setPosition(undefined);
        this._$popupCloser[0].blur();
        this.clearSelection();
        this._$popupContent.html('');

        return false;
    };

    /**
     *
     * @param {popupChangedFunction} chgFunction - popup change function
     */
    addPopupChangedFunction(chgFunction) {
        this._popupChangedFunctions.push(chgFunction);
    }

    /**
     *
     * @param {LayerBase|*} lyr - the layer being acted on
     * @param {object} [selectionStyle={}] the selection style configuration
     * @param {string} [selectionStyle.color=rgba(255,170,0,0.5)] the selection color
     * @param {number} [selectionStyle.width=10] the selection width for linear features
     * @param {object|function} [selectionStyle.olStyle=undefined] an openlayers style object or function
     * @returns {ol.layer.Vector} the new selection layer
     * @private
     */
    _addPopupLayer(lyr, selectionStyle) {
        this._checkInit();

        selectionStyle = selectionStyle || {};
        selectionStyle.color = selectionStyle.color || 'rgba(255,170,0,0.5)';
        selectionStyle.width = selectionStyle.width || 10;

        let theStyle;

        if (selectionStyle.olStyle) {
            theStyle = selectionStyle.olStyle;
        } else {
            theStyle = new ol.style.Style({
                stroke: new ol.style.Stroke({
                    color: selectionStyle.color,
                    width: selectionStyle.width
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({color: selectionStyle.color}),
                    stroke: new ol.style.Stroke({color: selectionStyle.color, width: 1})
                }),
                fill: new ol.style.Fill({
                    color: selectionStyle.color
                })
            });
        }

        let selectionLayer = new ol.layer.Vector(
            {
                source: new ol.source.Vector(),
                style: theStyle,
                zIndex: 100
            }
        );

        this._selectionLayers.push(selectionLayer);
        this._selectionLayerLookup[lyr.id] = selectionLayer;
        this.map.addLayer(selectionLayer);

        return selectionLayer;
    }

    /**
     * The popup callback function
     * @callback popupCallback
     * @param {object} featureProperties - the feature properties
     * @param {jQuery} jqRef reference to the div content to do some async stuff inside the div
     * @returns {string} the html content to be added to the popup
     */

    /**
     * Add popup to the map
     * @param {LayerBase|*} lyr The layer that the popup with act on
     * @param {popupCallback} popupContentFunction - popup content function that makes popup info
     * @param {object} [selectionStyle={}] the selection style configuration
     * @param {string} [selectionStyle.color=rgba(255,170,0,0.5)] the selection color
     * @param {number} [selectionStyle.width=10] the selection width for linear features
     * @param {object|function} [selectionStyle.olStyle=undefined] an openlayers style object or function
     * @returns {object} a reference to the ol selection layer
     */
    addVectorPopup(lyr, popupContentFunction, selectionStyle) {
        let selectionLayer = this._addPopupLayer(lyr, selectionStyle);
        this._arrPopupLayerIds.push(lyr.id);
        this._arrPopupLayerNames.push(lyr.name);
        this._arrPopupLayers.push(lyr);
        this._arrPopupOlLayers.push(lyr.olLayer);
        this._arrPopupContentFunction.push(popupContentFunction);

        return selectionLayer;
    };

    /**
     *
     * @param {LayerBase} lyr - layer
     */
    removeVectorPopup(lyr) {
        let idx = this._arrPopupLayerIds.indexOf(lyr.id);

        if (idx > -1) {
            this._arrPopupLayerIds.splice(idx, 1);
            this._arrPopupLayerNames.splice(idx, 1);
            this._arrPopupLayers.splice(idx, 1);
            this._arrPopupOlLayers.splice(idx, 1);
            this._arrPopupContentFunction.splice(idx, 1);
            this._selectionLayers.splice(idx, 1);
            delete this._selectionLayerLookup[lyr.id];
        }
    }

    /**
     *
     * @param {LayerEsriMapServer} lyr - map server layer
     * @param {object} [selectionStyle={}] the selection style configuration
     * @param {string} [selectionStyle.color=rgba(255,170,0,0.5)] the selection color
     * @param {number} [selectionStyle.width=10] the selection width for linear features
     * @param {object|function} [selectionStyle.olStyle=undefined] an openlayers style object or function
     * @returns {object} a reference to the ol selection layer
     */
    addMapServicePopup(lyr, selectionStyle) {
        let selectionLayer = this._addPopupLayer(lyr, selectionStyle);
        this._esriMapServiceLayers.push(lyr);

        return selectionLayer;
    }

    clearSelection() {
        this._checkInit();
        for (let i = 0; i &lt; this._selectionLayers.length; i++) {
            this._selectionLayers[i].getSource().clear();
        }
        for (let f of this._mapClickFunctions) {
            f();
        }
    };

    /**
     * Add a function to be called when the map is clicked but before any popups are implemented
     * @param {function} func - the map click function
     */
    addMapClickFunction(func) {
        this._mapClickFunctions.push(func);
    }
}
nm.MapPopupCls = MapPopupCls;
export default MapPopupCls;
</code></pre>
        </article>
    </section>




</div>

<nav>
Glenn Vorhes's avatar
Glenn Vorhes committed
    <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="-_FeatureLayerProperties.html">_FeatureLayerProperties</a></li><li><a href="-_Slider.html">_Slider</a></li><li><a href="CommonSymbol.html">CommonSymbol</a></li><li><a href="DayRange.html">DayRange</a></li><li><a href="ItsLayerCollection.html">ItsLayerCollection</a></li><li><a href="LayerBase.html">LayerBase</a></li><li><a href="LayerBaseVector.html">LayerBaseVector</a></li><li><a href="LayerBaseVectorEsri.html">LayerBaseVectorEsri</a></li><li><a href="LayerBaseVectorGeoJson.html">LayerBaseVectorGeoJson</a></li><li><a href="LayerBaseXyzTile.html">LayerBaseXyzTile</a></li><li><a href="LayerEsriMapServer.html">LayerEsriMapServer</a></li><li><a href="LayerEsriTile.html">LayerEsriTile</a></li><li><a href="LayerGroup.html">LayerGroup</a></li><li><a href="LayerItsInventory.html">LayerItsInventory</a></li><li><a href="LayerLegend.html">LayerLegend</a></li><li><a href="LayerRealEarthTile.html">LayerRealEarthTile</a></li><li><a href="LayerSwipe.html">LayerSwipe</a></li><li><a href="LayerVectorRealEarth.html">LayerVectorRealEarth</a></li><li><a href="MapInteractionBase.html">MapInteractionBase</a></li><li><a href="MapMoveCls.html">MapMoveCls</a></li><li><a href="MapPopupCls.html">MapPopupCls</a></li><li><a href="RealEarthAnimate.html">RealEarthAnimate</a></li><li><a href="RealEarthAnimateTile.html">RealEarthAnimateTile</a></li><li><a href="RealEarthAnimateVector.html">RealEarthAnimateVector</a></li><li><a href="SingleSymbol.html">SingleSymbol</a></li><li><a href="Sliders.html">Sliders</a></li><li><a href="SortedFeatures.html">SortedFeatures</a></li><li><a href="UniqueValueSymbol.html">UniqueValueSymbol</a></li></ul><h3>Global</h3><ul><li><a href="global.html#$">$</a></li><li><a href="global.html#bundleEs2015Multiple">bundleEs2015Multiple</a></li><li><a href="global.html#calculateExtent">calculateExtent</a></li><li><a href="global.html#dateToYyyyMmDdHh000">dateToYyyyMmDdHh000</a></li><li><a href="global.html#dateToYyyyMmDdHhMmSs">dateToYyyyMmDdHhMmSs</a></li><li><a href="global.html#definedAndNotNull">definedAndNotNull</a></li><li><a href="global.html#defineLegend">defineLegend</a></li><li><a href="global.html#defineStyle">defineStyle</a></li><li><a href="global.html#fitToMap">fitToMap</a></li><li><a href="global.html#getUrlParams">getUrlParams</a></li><li><a href="global.html#gulp">gulp</a></li><li><a href="global.html#hexAlphaToRgbOrRgba">hexAlphaToRgbOrRgba</a></li><li><a href="global.html#htmlEscape">htmlEscape</a></li><li><a href="global.html#keyValPairs">keyValPairs</a></li><li><a href="global.html#makeBlueGreenRedGradient">makeBlueGreenRedGradient</a></li><li><a href="global.html#makeBlueGreenRedGradientZScore">makeBlueGreenRedGradientZScore</a></li><li><a href="global.html#makeFeatureServiceLegendAndSymbol">makeFeatureServiceLegendAndSymbol</a></li><li><a href="global.html#makeGuid">makeGuid</a></li><li><a href="global.html#makeMapServiceLegend">makeMapServiceLegend</a></li><li><a href="global.html#mapServiceLegendItem">mapServiceLegendItem</a></li><li><a href="global.html#offsetMinutes">offsetMinutes</a></li><li><a href="global.html#overflowScroll">overflowScroll</a></li><li><a href="global.html#processLessFile">processLessFile</a></li><li><a href="global.html#propertiesZoomStyle">propertiesZoomStyle</a></li><li><a href="global.html#provide">provide</a></li><li><a href="global.html#quickMap">quickMap</a></li><li><a href="global.html#quickMapBase">quickMapBase</a></li><li><a href="global.html#quickMapMulti">quickMapMulti</a></li><li><a href="global.html#resolutionToZoom">resolutionToZoom</a></li><li><a href="global.html#responsiveScroll">responsiveScroll</a></li><li><a href="global.html#rgb2hex">rgb2hex</a></li><li><a href="global.html#rgbToRgba">rgbToRgba</a></li><li><a href="global.html#triggerCallback">triggerCallback</a></li><li><a href="global.html#undefinedOrNull">undefinedOrNull</a></li><li><a href="global.html#windowScroll">windowScroll</a></li><li><a href="global.html#zoomToResolution">zoomToResolution</a></li></ul>
</nav>

<br class="clear">

<footer>
Glenn Vorhes's avatar
Glenn Vorhes committed
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Mon Jul 18 2016 20:02:34 GMT-0500 (Central Daylight Time)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>