<!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. */ import $ from '../jquery/jquery'; import MapInteractionBase from './mapInteractionBase'; import propertiesZoomStyle from '../olHelpers/propertiesZoomStyle'; import provide from '../util/provide'; import ol from '../ol/ol'; 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 * &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<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<LayerEsriMapServer>} * @private */ this._esriMapServiceLayers = []; this._popupOpen = false; this._popupCoordinate = null; /** * * @type {Array.<_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( '<div class="ol-popup">' + '<span class="ol-popup-closer">X</span>' + '<div class="popup-content"></div>' + '</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); 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.<_FeatureLayerProperties>} */ this._passThroughLayerFeatureArray = []; this._currentPopupIndex = -1; for (let i = 0; i < 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 = '<div class="ol-popup-nav">'; popupHtml += '<span class="previous-popup ol-popup-nav-arrow">&#9664;</span>'; popupHtml += '<span class="next-popup ol-popup-nav-arrow">&#9654;</span>'; popupHtml += `<span class="current-popup-item-number" style="font-weight: bold;"></span>`; popupHtml += `<span>&nbsp;of&nbsp;</span>`; popupHtml += `<span class="popup-content-length" style="font-weight: bold;">${this._popupContentLength}</span>`; popupHtml += `<span>&nbsp;&nbsp;-&nbsp;&nbsp;</span>`; popupHtml += `<span class="current-popup-layer-name"></span>`; popupHtml += '</div>'; popupHtml += '<div class="ol-popup-inner">'; popupHtml += '</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 && 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.<_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 < 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> <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> 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>