diff --git a/maplibre/srcjs/index.js b/maplibre/srcjs/index.js index 8af087a7..a4a8cda5 100644 --- a/maplibre/srcjs/index.js +++ b/maplibre/srcjs/index.js @@ -1,7 +1,7 @@ -(()=>{var $=Object.prototype.toString,C=Array.isArray||function(e){return $.call(e)==="[object Array]"};function R(r){return typeof r=="function"}function B(r){return C(r)?"array":typeof r}function P(r){return r.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function j(r,e){return r!=null&&typeof r=="object"&&e in r}function A(r,e){return r!=null&&typeof r!="object"&&r.hasOwnProperty&&r.hasOwnProperty(e)}var J=RegExp.prototype.test;function F(r,e){return J.call(r,e)}var W=/\S/;function q(r){return!F(W,r)}var G={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function K(r){return String(r).replace(/[&<>"'`=\/]/g,function(t){return G[t]})}var V=/\s*/,z=/\s+/,D=/\s*=/,Q=/\s*\}/,X=/#|\^|\/|>|\{|&|=|!/;function Y(r,e){if(!r)return[];var t=!1,n=[],a=[],s=[],o=!1,p=!1,i="",u=0;function f(){if(o&&!p)for(;s.length;)delete a[s.pop()];else s=[];o=!1,p=!1}var v,m,N;function U(y){if(typeof y=="string"&&(y=y.split(z,2)),!C(y)||y.length!==2)throw new Error("Invalid tags: "+y);v=new RegExp(P(y[0])+"\\s*"),m=new RegExp("\\s*"+P(y[1])),N=new RegExp("\\s*"+P("}"+y[1]))}U(e||g.tags);for(var l=new T(r),w,d,h,_,L,b;!l.eos();){if(w=l.pos,h=l.scanUntil(v),h)for(var E=0,I=h.length;E"?L=[d,h,w,l.pos,i,u,t]:L=[d,h,w,l.pos],u++,a.push(L),d==="#"||d==="^")n.push(L);else if(d==="/"){if(b=n.pop(),!b)throw new Error('Unopened section "'+h+'" at '+w);if(b[1]!==h)throw new Error('Unclosed section "'+b[1]+'" at '+w)}else d==="name"||d==="{"||d==="&"?p=!0:d==="="&&U(h)}if(f(),b=n.pop(),b)throw new Error('Unclosed section "'+b[1]+'" at '+l.pos);return ee(Z(a))}function Z(r){for(var e=[],t,n,a=0,s=r.length;a0?n[n.length-1][4]:e;break;default:t.push(a)}return e}function T(r){this.string=r,this.tail=r,this.pos=0}T.prototype.eos=function(){return this.tail===""};T.prototype.scan=function(e){var t=this.tail.match(e);if(!t||t.index!==0)return"";var n=t[0];return this.tail=this.tail.substring(n.length),this.pos+=n.length,n};T.prototype.scanUntil=function(e){var t=this.tail.search(e),n;switch(t){case-1:n=this.tail,this.tail="";break;case 0:n="";break;default:n=this.tail.substring(0,t),this.tail=this.tail.substring(t)}return this.pos+=n.length,n};function k(r,e){this.view=r,this.cache={".":this.view},this.parent=e}k.prototype.push=function(e){return new k(e,this)};k.prototype.lookup=function(e){var t=this.cache,n;if(t.hasOwnProperty(e))n=t[e];else{for(var a=this,s,o,p,i=!1;a;){if(e.indexOf(".")>0)for(s=a.view,o=e.split("."),p=0;s!=null&&p"?u=this.renderPartial(p,t,n,s):i==="&"?u=this.unescapedValue(p,t):i==="name"?u=this.escapedValue(p,t,s):i==="text"&&(u=this.rawValue(p)),u!==void 0&&(o+=u);return o};c.prototype.renderSection=function(e,t,n,a,s){var o=this,p="",i=t.lookup(e[1]);function u(m){return o.render(m,t,n,s)}if(i){if(C(i))for(var f=0,v=i.length;f0||!n)&&(s[o]=a+s[o]);return s.join(` -`)};c.prototype.renderPartial=function(e,t,n,a){if(n){var s=this.getConfigTags(a),o=R(n)?n(e[1]):n[e[1]];if(o!=null){var p=e[6],i=e[5],u=e[4],f=o;i==0&&u&&(f=this.indentPartial(o,u,p));var v=this.parse(f,s);return this.renderTokens(v,t,n,f,a)}}};c.prototype.unescapedValue=function(e,t){var n=t.lookup(e[1]);if(n!=null)return n};c.prototype.escapedValue=function(e,t,n){var a=this.getConfigEscape(n)||g.escape,s=t.lookup(e[1]);if(s!=null)return typeof s=="number"&&a===g.escape?String(s):a(s)};c.prototype.rawValue=function(e){return e[1]};c.prototype.getConfigTags=function(e){return C(e)?e:e&&typeof e=="object"?e.tags:void 0};c.prototype.getConfigEscape=function(e){if(e&&typeof e=="object"&&!C(e))return e.escape};var g={name:"mustache.js",version:"4.2.0",tags:["{{","}}"],clearCache:void 0,escape:void 0,parse:void 0,render:void 0,Scanner:void 0,Context:void 0,Writer:void 0,set templateCache(r){O.templateCache=r},get templateCache(){return O.templateCache}},O=new c;g.clearCache=function(){return O.clearCache()};g.parse=function(e,t){return O.parse(e,t)};g.render=function(e,t,n,a){if(typeof e!="string")throw new TypeError('Invalid template! Template should be a "string" but "'+B(e)+'" was given as the first argument for mustache#render(template, view, partials)');return O.render(e,t,n,a)};g.escape=K;g.Scanner=T;g.Context=k;g.Writer=c;var M=g;function x(r,e,t){return t!==null?M.render(t,r.properties):e===null?Object.keys(r.properties).map(a=>`${a}: ${r.properties[a]}`).join("
"):r.properties[e]}function te(r,e,t){return typeof r=="object"?r[t]&&M.render(r[t],e):{html:M.render(r,e),style:{background:"white",color:"black","border-radius":"5px"}}}function H(r){return({layer:e,object:t})=>t&&te(r,t,e.id)}function ne(){if(typeof deck>"u")return;let r=new deck.JSONConfiguration({classes:deck});return new deck.JSONConverter({configuration:r})}var S=class{constructor(e){this._id=e.container,this._map=new maplibregl.Map(e),this._map.on("mouseover",()=>{this._map.getCanvas().style.cursor="pointer"}),this._map.on("mouseout",()=>{this._map.getCanvas().style.cursor=""}),this._map.addControl(new maplibregl.NavigationControl),this._JSONConverter=ne()}getMap(){return this._map}applyMapMethod(e,t){this._map[e](...t)}addControl(e,t,n){this._map.addControl(new maplibregl[e](t),n)}addMarker({lngLat:e,popup:t,options:n}){let a=new maplibregl.Marker(n).setLngLat(e);if(t){let s=new maplibregl.Popup(t.options).setHTML(t.text);a.setPopup(s)}a.addTo(this._map)}addLayer(e,t){this._map.addLayer(e,t),typeof Shiny<"u"&&this._map.on("click",e.id,n=>{console.log(n,n.features[0]);let a=e.id.replaceAll("-","_"),s=`${this._id}_layer_${a}`,o={props:n.features[0].properties,layer_id:e.id};console.log(s,o),Shiny.onInputChange(s,o)})}addPopup(e,t=null,n=null){let a={closeButton:!1},s=new maplibregl.Popup(a);this._map.on("click",e,o=>{let p=o.features[0],i=x(p,t,n);s.setLngLat(o.lngLat).setHTML(i).addTo(this._map)})}addTooltip(e,t=null,n=null){let a={closeButton:!1,closeOnClick:!1},s=new maplibregl.Popup(a);this._map.on("mousemove",e,o=>{let p=o.features[0],i=x(p,t,n);s.setLngLat(o.lngLat).setHTML(i).addTo(this._map)}),this._map.on("mouseleave",e,()=>{s.remove()})}setSourceData(e,t){this._map.getSource(e).setData(t)}addDeckOverlay(e,t=null){if(typeof this._JSONConverter>"u"){console.log("deck or JSONConverter is undefined");return}let n=e.map(s=>this._JSONConverter.convert(Object.assign(s,{onHover:({layer:o,coordinate:p,object:i})=>{if(typeof Shiny<"u"){let u=`${this._id}_layer_${s.id}`;Shiny.onInputChange(u,i)}}}))),a=new deck.MapboxOverlay({interleaved:!0,layers:n,getTooltip:t?H(t):null});this._map.addControl(a)}render(e){e.forEach(([t,n])=>{if(["addLayer","addPopup","addTooltip","addMarker","addPopup","addControl","setSourceData","addDeckOverlay"].includes(t)){console.log("Custom method",t,n),this[t](...n);return}console.log("Map method",t),this.applyMapMethod(t,n)})}};var re="0.1.0";console.log("pymaplibregl",re);typeof Shiny>"u"&&(window.pymaplibregl=function({mapOptions:r,calls:e}){let t="pymaplibregl",n=document.getElementById(t),a=new S(Object.assign({container:n.id},r));a.getMap().on("load",()=>{a.render(e)})});if(typeof Shiny<"u"){class r extends Shiny.OutputBinding{find(t){return t.find(".shiny-maplibregl-output")}renderValue(t,n){console.log("id:",t.id,"payload:",n);let a=window._maplibreWidget=new S(Object.assign({container:t.id},n.mapData.mapOptions)),s=a.getMap();s.on("load",()=>{a.render(n.mapData.calls)}),s.on("click",p=>{console.log(p);let i=`${t.id}`,u={coords:p.lngLat,point:p.point};console.log(i,u),Shiny.onInputChange(i,u)});let o=`pymaplibregl-${t.id}`;console.log(o),Shiny.addCustomMessageHandler(o,({id:p,calls:i})=>{console.log(p,i),a.render(i)})}}Shiny.outputBindings.register(new r,"shiny-maplibregl-output")}})(); +(()=>{var $=Object.prototype.toString,C=Array.isArray||function(e){return $.call(e)==="[object Array]"};function R(r){return typeof r=="function"}function B(r){return C(r)?"array":typeof r}function P(r){return r.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function j(r,e){return r!=null&&typeof r=="object"&&e in r}function A(r,e){return r!=null&&typeof r!="object"&&r.hasOwnProperty&&r.hasOwnProperty(e)}var J=RegExp.prototype.test;function F(r,e){return J.call(r,e)}var W=/\S/;function q(r){return!F(W,r)}var G={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function K(r){return String(r).replace(/[&<>"'`=\/]/g,function(t){return G[t]})}var V=/\s*/,z=/\s+/,D=/\s*=/,Q=/\s*\}/,X=/#|\^|\/|>|\{|&|=|!/;function Y(r,e){if(!r)return[];var t=!1,n=[],s=[],a=[],o=!1,u=!1,i="",l=0;function f(){if(o&&!u)for(;a.length;)delete s[a.pop()];else a=[];o=!1,u=!1}var v,m,N;function U(y){if(typeof y=="string"&&(y=y.split(z,2)),!C(y)||y.length!==2)throw new Error("Invalid tags: "+y);v=new RegExp(P(y[0])+"\\s*"),m=new RegExp("\\s*"+P(y[1])),N=new RegExp("\\s*"+P("}"+y[1]))}U(e||g.tags);for(var p=new T(r),w,d,h,_,L,b;!p.eos();){if(w=p.pos,h=p.scanUntil(v),h)for(var E=0,I=h.length;E"?L=[d,h,w,p.pos,i,l,t]:L=[d,h,w,p.pos],l++,s.push(L),d==="#"||d==="^")n.push(L);else if(d==="/"){if(b=n.pop(),!b)throw new Error('Unopened section "'+h+'" at '+w);if(b[1]!==h)throw new Error('Unclosed section "'+b[1]+'" at '+w)}else d==="name"||d==="{"||d==="&"?u=!0:d==="="&&U(h)}if(f(),b=n.pop(),b)throw new Error('Unclosed section "'+b[1]+'" at '+p.pos);return ee(Z(s))}function Z(r){for(var e=[],t,n,s=0,a=r.length;s0?n[n.length-1][4]:e;break;default:t.push(s)}return e}function T(r){this.string=r,this.tail=r,this.pos=0}T.prototype.eos=function(){return this.tail===""};T.prototype.scan=function(e){var t=this.tail.match(e);if(!t||t.index!==0)return"";var n=t[0];return this.tail=this.tail.substring(n.length),this.pos+=n.length,n};T.prototype.scanUntil=function(e){var t=this.tail.search(e),n;switch(t){case-1:n=this.tail,this.tail="";break;case 0:n="";break;default:n=this.tail.substring(0,t),this.tail=this.tail.substring(t)}return this.pos+=n.length,n};function k(r,e){this.view=r,this.cache={".":this.view},this.parent=e}k.prototype.push=function(e){return new k(e,this)};k.prototype.lookup=function(e){var t=this.cache,n;if(t.hasOwnProperty(e))n=t[e];else{for(var s=this,a,o,u,i=!1;s;){if(e.indexOf(".")>0)for(a=s.view,o=e.split("."),u=0;a!=null&&u"?l=this.renderPartial(u,t,n,a):i==="&"?l=this.unescapedValue(u,t):i==="name"?l=this.escapedValue(u,t,a):i==="text"&&(l=this.rawValue(u)),l!==void 0&&(o+=l);return o};c.prototype.renderSection=function(e,t,n,s,a){var o=this,u="",i=t.lookup(e[1]);function l(m){return o.render(m,t,n,a)}if(i){if(C(i))for(var f=0,v=i.length;f0||!n)&&(a[o]=s+a[o]);return a.join(` +`)};c.prototype.renderPartial=function(e,t,n,s){if(n){var a=this.getConfigTags(s),o=R(n)?n(e[1]):n[e[1]];if(o!=null){var u=e[6],i=e[5],l=e[4],f=o;i==0&&l&&(f=this.indentPartial(o,l,u));var v=this.parse(f,a);return this.renderTokens(v,t,n,f,s)}}};c.prototype.unescapedValue=function(e,t){var n=t.lookup(e[1]);if(n!=null)return n};c.prototype.escapedValue=function(e,t,n){var s=this.getConfigEscape(n)||g.escape,a=t.lookup(e[1]);if(a!=null)return typeof a=="number"&&s===g.escape?String(a):s(a)};c.prototype.rawValue=function(e){return e[1]};c.prototype.getConfigTags=function(e){return C(e)?e:e&&typeof e=="object"?e.tags:void 0};c.prototype.getConfigEscape=function(e){if(e&&typeof e=="object"&&!C(e))return e.escape};var g={name:"mustache.js",version:"4.2.0",tags:["{{","}}"],clearCache:void 0,escape:void 0,parse:void 0,render:void 0,Scanner:void 0,Context:void 0,Writer:void 0,set templateCache(r){O.templateCache=r},get templateCache(){return O.templateCache}},O=new c;g.clearCache=function(){return O.clearCache()};g.parse=function(e,t){return O.parse(e,t)};g.render=function(e,t,n,s){if(typeof e!="string")throw new TypeError('Invalid template! Template should be a "string" but "'+B(e)+'" was given as the first argument for mustache#render(template, view, partials)');return O.render(e,t,n,s)};g.escape=K;g.Scanner=T;g.Context=k;g.Writer=c;var M=g;function x(r,e,t){return t!==null?M.render(t,r.properties):e===null?Object.keys(r.properties).map(s=>`${s}: ${r.properties[s]}`).join("
"):r.properties[e]}function te(r,e,t){let n={background:"white",color:"black","border-radius":"5px"};return typeof r=="object"?r[t]&&{html:M.render(r[t],e),style:n}:{html:M.render(r,e),style:n}}function H(r){return({layer:e,object:t})=>t&&te(r,t,e.id)}function ne(){if(typeof deck>"u")return;let r=new deck.JSONConfiguration({classes:deck});return new deck.JSONConverter({configuration:r})}var S=class{constructor(e){this._id=e.container,this._map=new maplibregl.Map(e),this._map.on("mouseover",()=>{this._map.getCanvas().style.cursor="pointer"}),this._map.on("mouseout",()=>{this._map.getCanvas().style.cursor=""}),this._map.addControl(new maplibregl.NavigationControl),this._JSONConverter=ne()}getMap(){return this._map}applyMapMethod(e,t){this._map[e](...t)}addControl(e,t,n){this._map.addControl(new maplibregl[e](t),n)}addMarker({lngLat:e,popup:t,options:n}){let s=new maplibregl.Marker(n).setLngLat(e);if(t){let a=new maplibregl.Popup(t.options).setHTML(t.text);s.setPopup(a)}s.addTo(this._map)}addLayer(e,t){this._map.addLayer(e,t),typeof Shiny<"u"&&this._map.on("click",e.id,n=>{console.log(n,n.features[0]);let s=e.id.replaceAll("-","_"),a=`${this._id}_layer_${s}`,o={props:n.features[0].properties,layer_id:e.id};console.log(a,o),Shiny.onInputChange(a,o)})}addPopup(e,t=null,n=null){let s={closeButton:!1},a=new maplibregl.Popup(s);this._map.on("click",e,o=>{let u=o.features[0],i=x(u,t,n);a.setLngLat(o.lngLat).setHTML(i).addTo(this._map)})}addTooltip(e,t=null,n=null){let s={closeButton:!1,closeOnClick:!1},a=new maplibregl.Popup(s);this._map.on("mousemove",e,o=>{let u=o.features[0],i=x(u,t,n);a.setLngLat(o.lngLat).setHTML(i).addTo(this._map)}),this._map.on("mouseleave",e,()=>{a.remove()})}setSourceData(e,t){this._map.getSource(e).setData(t)}addDeckOverlay(e,t=null){if(typeof this._JSONConverter>"u"){console.log("deck or JSONConverter is undefined");return}let n=e.map(a=>this._JSONConverter.convert(Object.assign(a,{onHover:({layer:o,coordinate:u,object:i})=>{if(typeof Shiny<"u"){let l=`${this._id}_layer_${a.id}`;Shiny.onInputChange(l,i)}}}))),s=new deck.MapboxOverlay({interleaved:!0,layers:n,getTooltip:t?H(t):null});this._map.addControl(s)}render(e){e.forEach(([t,n])=>{if(["addLayer","addPopup","addTooltip","addMarker","addPopup","addControl","setSourceData","addDeckOverlay"].includes(t)){console.log("Custom method",t,n),this[t](...n);return}console.log("Map method",t),this.applyMapMethod(t,n)})}};var re="0.1.0";console.log("pymaplibregl",re);typeof Shiny>"u"&&(window.pymaplibregl=function({mapOptions:r,calls:e}){let t="pymaplibregl",n=document.getElementById(t),s=new S(Object.assign({container:n.id},r));s.getMap().on("load",()=>{s.render(e)})});if(typeof Shiny<"u"){class r extends Shiny.OutputBinding{find(t){return t.find(".shiny-maplibregl-output")}renderValue(t,n){console.log("id:",t.id,"payload:",n);let s=window._maplibreWidget=new S(Object.assign({container:t.id},n.mapData.mapOptions)),a=s.getMap();a.on("load",()=>{s.render(n.mapData.calls)}),a.on("click",u=>{console.log(u);let i=`${t.id}`,l={coords:u.lngLat,point:u.point};console.log(i,l),Shiny.onInputChange(i,l)});let o=`pymaplibregl-${t.id}`;console.log(o),Shiny.addCustomMessageHandler(o,({id:u,calls:i})=>{console.log(u,i),s.render(i)})}}Shiny.outputBindings.register(new r,"shiny-maplibregl-output")}})(); /*! Bundled license information: mustache/mustache.mjs: diff --git a/srcjs/utils.js b/srcjs/utils.js index 2f41e25c..f3942fef 100644 --- a/srcjs/utils.js +++ b/srcjs/utils.js @@ -17,13 +17,23 @@ function getTextFromFeature(feature, property, template) { function renderPickingObject(template, object, layerId) { // console.log("Trying to get tooltip for layerId = " + layerId); + const default_style = { + background: "white", + color: "black", + "border-radius": "5px", + }; if (typeof template === "object") { - return template[layerId] && mustache.render(template[layerId], object); + return ( + template[layerId] && { + html: mustache.render(template[layerId], object), + style: default_style, + } + ); } return { html: mustache.render(template, object), - style: { background: "white", color: "black", "border-radius": "5px" }, + style: default_style, }; } @@ -40,10 +50,12 @@ function deckLayerOnHover(map, tooltip_template) { closeOnClick: false, closeButton: false, }); + map.on("mouseout", (e) => popup.remove()); return ({ layer, coordinate, object }) => { if (object) { + console.log(tooltip_template); popup - .setHTML(getDeckTooltip(tooltip_template)({ layer, object })) + .setHTML(mustache.render(tooltip_template, object)) .setLngLat(coordinate); popup.addTo(map); } else popup.remove();