From 1e3bf9729eae72f7b5c1a71ad952877486a0fcdb Mon Sep 17 00:00:00 2001 From: Marc Tobias Metten Date: Sun, 19 Mar 2017 17:31:00 +0100 Subject: [PATCH] for search,details in format=HTML return geometry in geojson, not wkt. No longer need leaflet-omnivore plugin --- lib/template/details-html.php | 2 +- lib/template/includes/html-footer.php | 1 - lib/template/search-html.php | 4 +- website/details.php | 4 +- website/js/leaflet-omnivore.min.js | 1 - website/js/nominatim-ui.js | 54 ++++++++++++++++++++------- website/search.php | 4 +- 7 files changed, 47 insertions(+), 23 deletions(-) delete mode 100644 website/js/leaflet-omnivore.min.js diff --git a/lib/template/details-html.php b/lib/template/details-html.php index a1334740..46b6a50c 100644 --- a/lib/template/details-html.php +++ b/lib/template/details-html.php @@ -241,7 +241,7 @@ echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';'; $aPlace = array( - 'outlinestring' => $aPointDetails['outlinestring'], + 'asgeojson' => $aPointDetails['asgeojson'], 'lon' => $aPointDetails['lon'], 'lat' => $aPointDetails['lat'], ); diff --git a/lib/template/includes/html-footer.php b/lib/template/includes/html-footer.php index a38e45dd..b5ebb137 100644 --- a/lib/template/includes/html-footer.php +++ b/lib/template/includes/html-footer.php @@ -10,5 +10,4 @@ - diff --git a/lib/template/search-html.php b/lib/template/search-html.php index 14ebacc8..115f1813 100644 --- a/lib/template/search-html.php +++ b/lib/template/search-html.php @@ -17,8 +17,8 @@
- - + +
diff --git a/website/details.php b/website/details.php index 0dc3397a..0025a8ba 100755 --- a/website/details.php +++ b/website/details.php @@ -99,10 +99,10 @@ $sSQL .= " CASE "; $sSQL .= " WHEN importance = 0 OR importance IS NULL THEN 0.75-(rank_search::float/40) "; $sSQL .= " ELSE importance "; $sSQL .= " END as calculated_importance, "; -$sSQL .= " ST_AsText(CASE "; +$sSQL .= " ST_AsGeoJSON(CASE "; $sSQL .= " WHEN ST_NPoints(geometry) > 5000 THEN ST_SimplifyPreserveTopology(geometry, 0.0001) "; $sSQL .= " ELSE geometry "; -$sSQL .= " END) as outlinestring"; +$sSQL .= " END) as asgeojson"; $sSQL .= " FROM placex "; $sSQL .= " WHERE place_id = $iPlaceID"; diff --git a/website/js/leaflet-omnivore.min.js b/website/js/leaflet-omnivore.min.js deleted file mode 100644 index 5c572825..00000000 --- a/website/js/leaflet-omnivore.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.omnivore=e()}}(function(){var e;return function r(e,n,t){function o(u,a){if(!n[u]){if(!e[u]){var s="function"==typeof require&&require;if(!a&&s)return s(u,!0);if(i)return i(u,!0);var f=new Error("Cannot find module '"+u+"'");throw f.code="MODULE_NOT_FOUND",f}var c=n[u]={exports:{}};e[u][0].call(c.exports,function(n){var r=e[u][1][n];return o(r?r:n)},c,c.exports,r,e,n,t)}return n[u].exports}for(var i="function"==typeof require&&require,u=0;u0)){var r=t.shift();r()}},!0),function(e){t.push(e),window.postMessage("process-tick","*")}):function(e){setTimeout(e,0)}}(),t.title="browser",t.browser=!0,t.env={},t.argv=[],t.on=r,t.addListener=r,t.once=r,t.off=r,t.removeListener=r,t.removeAllListeners=r,t.emit=r,t.binding=function(){throw new Error("process.binding is not supported")},t.cwd=function(){return"/"},t.chdir=function(){throw new Error("process.chdir is not supported")}},{}],5:[function(e,n){function r(e,n,r){function t(e){return e>=200&&300>e||304===e}function o(){void 0===a.status||t(a.status)?n.call(a,null,a):n.call(a,a,null)}var i=!1;if("undefined"==typeof window.XMLHttpRequest)return n(Error("Browser not supported"));if("undefined"==typeof r){var u=e.match(/^\s*https?:\/\/[^\/]*/);r=u&&u[0]!==location.protocol+"//"+location.domain+(location.port?":"+location.port:"")}var a=new window.XMLHttpRequest;if(r&&!("withCredentials"in a)){a=new window.XDomainRequest;var s=n;n=function(){if(i)s.apply(this,arguments);else{var e=this,n=arguments;setTimeout(function(){s.apply(e,n)},0)}}}return"onload"in a?a.onload=o:a.onreadystatechange=function(){4===a.readyState&&o()},a.onerror=function(e){n.call(this,e||!0,null),n=function(){}},a.onprogress=function(){},a.ontimeout=function(e){n.call(this,e,null),n=function(){}},a.onabort=function(e){n.call(this,e,null),n=function(){}},a.open("GET",e,!0),a.send(null),i=!0,a}"undefined"!=typeof n&&(n.exports=r)},{}],6:[function(e,n){function r(e){return!!e.match(/(Lat)(itude)?/gi)}function t(e){return!!e.match(/(L)(on|ng)(gitude)?/i)}function o(e){return"object"==typeof e?Object.keys(e).length:0}function i(e){var n=[",",";"," ","|"],r=[];return n.forEach(function(n){var t=c(n).parse(e);if(t.length>=1){for(var i=o(t[0]),u=0;u= N) return EOF; // special case: end of file\n if (eol) return eol = false, EOL; // special case: end of line\n\n // special case: quotes\n var j = I;\n if (text.charCodeAt(j) === 34) {\n var i = j;\n while (i++ < N) {\n if (text.charCodeAt(i) === 34) {\n if (text.charCodeAt(i + 1) !== 34) break;\n ++i;\n }\n }\n I = i + 2;\n var c = text.charCodeAt(i + 1);\n if (c === 13) {\n eol = true;\n if (text.charCodeAt(i + 2) === 10) ++I;\n } else if (c === 10) {\n eol = true;\n }\n return text.substring(j + 1, i).replace(/""/g, "\\"");\n }\n\n // common case: find next delimiter or newline\n while (I < N) {\n var c = text.charCodeAt(I++), k = 1;\n if (c === 10) eol = true; // \\n\n else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \\r|\\r\\n\n else if (c !== delimiterCode) continue;\n return text.substring(j, I - k);\n }\n\n // special case: last token before EOF\n return text.substring(j);\n }\n\n while ((t = token()) !== EOF) {\n var a = [];\n while (t !== EOL && t !== EOF) {\n a.push(t);\n t = token();\n }\n if (f && !(a = f(a, n++))) continue;\n rows.push(a);\n }\n\n return rows;\n };\n\n dsv.format = function(rows) {\n if (Array.isArray(rows[0])) return dsv.formatRows(rows); // deprecated; use formatRows\n var fieldSet = {}, fields = [];\n\n // Compute unique fields in order of discovery.\n rows.forEach(function(row) {\n for (var field in row) {\n if (!(field in fieldSet)) {\n fields.push(fieldSet[field] = field);\n }\n }\n });\n\n return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) {\n return fields.map(function(field) {\n return formatValue(row[field]);\n }).join(delimiter);\n })).join("\\n");\n };\n\n dsv.formatRows = function(rows) {\n return rows.map(formatRow).join("\\n");\n };\n\n function formatRow(row) {\n return row.map(formatValue).join(delimiter);\n }\n\n function formatValue(text) {\n return reFormat.test(text) ? "\\"" + text.replace(/\\"/g, "\\"\\"") + "\\"" : text;\n }\n\n return dsv;\n}\n;return dsv')()},{fs:2}],8:[function(e,n){n.exports=function(e,n){if(n||(n="NSEW"),"string"!=typeof e)return null;var r=/^([0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/,t=e.match(r);return t?t[4]&&-1===n.indexOf(t[4])?null:((t[1]?parseFloat(t[1]):0)+(t[2]?parseFloat(t[2])/60:0)+(t[3]?parseFloat(t[3])/3600:0))*(t[4]&&"S"===t[4]||"W"===t[4]?-1:1):null}},{}],9:[function(e,n){function r(e,n){e=Math.round(e*n),e<<=1,0>e&&(e=~e);for(var r="";e>=32;)r+=String.fromCharCode((32|31&e)+63),e>>=5;return r+=String.fromCharCode(e+63)}var t={};t.decode=function(e,n){for(var r,t,o=0,i=0,u=0,a=[],s=0,f=0,c=null,l=Math.pow(10,n||5);o=32);r=1&f?~(f>>1):f>>1,s=f=0;do c=e.charCodeAt(o++)-63,f|=(31&c)<=32);t=1&f?~(f>>1):f>>1,i+=r,u+=t,a.push([i/l,u/l])}return a},t.encode=function(e,n){if(!e.length)return"";for(var t=Math.pow(10,n||5),o=r(e[0][0],t)+r(e[0][1],t),i=1;iu)){for(var a=0;u>a;a++){var s=g(r[a]);t.push(s.coordinates),s.time&&i.push(s.time)}return{line:t,times:i}}}function r(e){for(var r,t=o(e,"trkseg"),i=[],a=[],s=0;sn?~n:n],o=t[0];return e.transform?(r=[0,0],t.forEach(function(e){r[0]+=e[0],r[1]+=e[1]})):r=t[t.length-1],0>n?[r,o]:[o,r]}function t(e,n){for(var r in e){var t=e[r];delete n[t.start],delete t.start,delete t.end,t.forEach(function(e){o[0>e?~e:e]=1}),a.push(t)}}var o={},i={},u={},a=[],s=-1;return n.forEach(function(r,t){var o,i=e.arcs[0>r?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=n[++s],n[s]=r,n[t]=o)}),n.forEach(function(e){var n,t,o=r(e),a=o[0],s=o[1];if(n=u[a])if(delete u[n.end],n.push(e),n.end=s,t=i[s]){delete i[t.start];var f=t===n?n:n.concat(t);i[f.start=n.start]=u[f.end=t.end]=f}else i[n.start]=u[n.end]=n;else if(n=i[s])if(delete i[n.start],n.unshift(e),n.start=a,t=u[a]){delete u[t.end];var c=t===n?n:t.concat(n);i[c.start=t.start]=u[c.end=n.end]=c}else i[n.start]=u[n.end]=n;else n=[e],i[n.start=a]=u[n.end=s]=n}),t(u,i),t(i,u),n.forEach(function(e){o[0>e?~e:e]||a.push([e])}),a}function o(e,n,t){function o(e){var n=0>e?~e:e;(c[n]||(c[n]=[])).push({i:e,g:f})}function i(e){e.forEach(o)}function u(e){e.forEach(i)}function a(e){"GeometryCollection"===e.type?e.geometries.forEach(a):e.type in l&&(f=e,l[e.type](e.arcs))}var s=[];if(arguments.length>1){var f,c=[],l={LineString:i,MultiLineString:u,Polygon:u,MultiPolygon:function(e){e.forEach(u)}};a(n),c.forEach(arguments.length<3?function(e){s.push(e[0].i)}:function(e){t(e[0].g,e[e.length-1].g)&&s.push(e[0].i)})}else for(var p=0,d=e.arcs.length;d>p;++p)s.push(p);return{type:"MultiLineString",arcs:r(e,s)}}function i(e,t){function o(e){e.forEach(function(n){n.forEach(function(n){(u[n=0>n?~n:n]||(u[n]=[])).push(e)})}),a.push(e)}function i(n){return d(s(e,{type:"Polygon",arcs:[n]}).coordinates[0])>0}var u={},a=[],f=[];return t.forEach(function(e){"Polygon"===e.type?o(e.arcs):"MultiPolygon"===e.type&&e.arcs.forEach(o)}),a.forEach(function(e){if(!e._){var n=[],r=[e];for(e._=1,f.push(n);e=r.pop();)n.push(e),e.forEach(function(e){e.forEach(function(e){u[0>e?~e:e].forEach(function(e){e._||(e._=1,r.push(e))})})})}}),a.forEach(function(e){delete e._}),{type:"MultiPolygon",arcs:f.map(function(t){var o=[];if(t.forEach(function(e){e.forEach(function(e){e.forEach(function(e){u[0>e?~e:e].length<2&&o.push(e)})})}),o=r(e,o),(n=o.length)>1)for(var a,s=i(t[0][0]),f=0;fe?~e:e],o=0,i=t.length;i>o;++o)n.push(r=t[o].slice()),s(r,o);0>e&&f(n,i)}function t(e){return e=e.slice(),s(e,0),e}function o(e){for(var n=[],t=0,o=e.length;o>t;++t)r(e[t],n);return n.length<2&&n.push(n[0].slice()),n}function i(e){for(var n=o(e);n.length<4;)n.push(n[0].slice());return n}function u(e){return e.map(i)}function a(e){var n=e.type;return"GeometryCollection"===n?{type:n,geometries:e.geometries.map(a)}:n in l?{type:n,coordinates:l[n](e)}:null}var s=m(e.transform),c=e.arcs,l={Point:function(e){return t(e.coordinates)},MultiPoint:function(e){return e.coordinates.map(t)},LineString:function(e){return o(e.arcs)},MultiLineString:function(e){return e.arcs.map(o)},Polygon:function(e){return u(e.arcs)},MultiPolygon:function(e){return e.arcs.map(u)}};return a(n)}function f(e,n){for(var r,t=e.length,o=t-n;o<--t;)r=e[o],e[o++]=e[t],e[t]=r}function c(e,n){for(var r=0,t=e.length;t>r;){var o=r+t>>>1;e[o]e&&(e=~e);var r=o[e];r?r.push(n):o[e]=[n]})}function r(e,r){e.forEach(function(e){n(e,r)})}function t(e,n){"GeometryCollection"===e.type?e.geometries.forEach(function(e){t(e,n)}):e.type in u&&u[e.type](e.arcs,n)}var o={},i=e.map(function(){return[]}),u={LineString:n,MultiLineString:r,Polygon:r,MultiPolygon:function(e,n){e.forEach(function(e){r(e,n)})}};e.forEach(t);for(var a in o)for(var s=o[a],f=s.length,l=0;f>l;++l)for(var p=l+1;f>p;++p){var d,g=s[l],h=s[p];(d=i[g])[a=c(d,h)]!==h&&d.splice(a,0,h),(d=i[h])[a=c(d,g)]!==g&&d.splice(a,0,g)}return i}function p(e,n){function r(e){u.remove(e),e[1][2]=n(e),u.push(e)}var t,o=m(e.transform),i=y(e.transform),u=v(),a=0;for(n||(n=g),e.arcs.forEach(function(e){var r=[];e.forEach(o);for(var i=1,a=e.length-1;a>i;++i)t=e.slice(i-1,i+2),t[1][2]=n(t),r.push(t),u.push(t);e[0][2]=e[a][2]=1/0;for(var i=0,a=r.length;a>i;++i)t=r[i],t.previous=r[i-1],t.next=r[i+1]});t=u.pop();){var s=t.previous,f=t.next;t[1][2]0;){var r=(n+1>>1)-1,o=t[r];if(h(e,o)>=0)break;t[o._=n]=o,t[e._=n=r]=e}}function n(e,n){for(;;){var r=n+1<<1,i=r-1,u=n,a=t[u];if(o>i&&h(t[i],a)<0&&(a=t[u=i]),o>r&&h(t[r],a)<0&&(a=t[u=r]),u===n)break;t[a._=n]=a,t[e._=n=u]=e}}var r={},t=[],o=0;return r.push=function(n){return e(t[n._=o]=n,o++),o},r.pop=function(){if(!(0>=o)){var e,r=t[0];return--o>0&&(e=t[o],n(t[e._=0]=e,0)),r}},r.remove=function(r){var i,u=r._;if(t[u]===r)return u!==--o&&(i=t[o],(h(i,r)<0?e:n)(t[i._=u]=i,u)),u},r}function m(e){if(!e)return w;var n,r,t=e.scale[0],o=e.scale[1],i=e.translate[0],u=e.translate[1];return function(e,a){a||(n=r=0),e[0]=(n+=e[0])*t+i,e[1]=(r+=e[1])*o+u}}function y(e){if(!e)return w;var n,r,t=e.scale[0],o=e.scale[1],i=e.translate[0],u=e.translate[1];return function(e,a){a||(n=r=0);var s=(e[0]-i)/t|0,f=(e[1]-u)/o|0;e[0]=s-n,e[1]=f-r,n=s,r=f}}function w(){}var x={version:"1.6.8",mesh:function(e){return s(e,o.apply(this,arguments))},meshArcs:o,merge:function(e){return s(e,i.apply(this,arguments))},mergeArcs:i,feature:u,neighbors:l,presimplify:p};"function"==typeof e&&e.amd?e(x):"object"==typeof t&&t.exports?t.exports=x:this.topojson=x}()},{}],12:[function(e,n){function r(e){function n(n){var r=e.substring(m).match(n);return r?(m+=r[0].length,r[0]):null}function r(e){return e&&v.match(/\d+/)&&(e.crs={type:"name",properties:{name:"urn:ogc:def:crs:EPSG::"+v}}),e}function t(){n(/^\s*/)}function i(){t();for(var e,r=0,i=[],u=[i],a=i;e=n(/^(\()/)||n(/^(\))/)||n(/^(\,)/)||n(o);){if("("==e)u.push(a),a=[],u[u.length-1].push(a),r++;else if(")"==e){if(a=u.pop(),!a)return;if(r--,0===r)break}else if(","===e)a=[],u[u.length-1].push(a);else{if(isNaN(parseFloat(e)))return null;a.push(parseFloat(e))}t()}return 0!==r?null:i}function u(){for(var e,r,i=[];r=n(o)||n(/^(\,)/);)","==r?(i.push(e),e=[]):(e||(e=[]),e.push(parseFloat(r))),t();return e&&i.push(e),i.length?i:null}function a(){if(!n(/^(point)/i))return null;if(t(),!n(/^(\()/))return null;var e=u();return e?(t(),n(/^(\))/)?{type:"Point",coordinates:e[0]}:null):null}function s(){if(!n(/^(multipoint)/i))return null;t();var e=i();return e?(t(),{type:"MultiPoint",coordinates:e}):null}function f(){if(!n(/^(multilinestring)/i))return null;t();var e=i();return e?(t(),{type:"MultiLineString",coordinates:e}):null}function c(){if(!n(/^(linestring)/i))return null;if(t(),!n(/^(\()/))return null;var e=u();return e&&n(/^(\))/)?{type:"LineString",coordinates:e}:null}function l(){return n(/^(polygon)/i)?(t(),{type:"Polygon",coordinates:i()}):null}function p(){return n(/^(multipolygon)/i)?(t(),{type:"MultiPolygon",coordinates:i()}):null}function d(){var e,r=[];if(!n(/^(geometrycollection)/i))return null;if(t(),!n(/^(\()/))return null;for(;e=g();)r.push(e),t(),n(/^(\,)/),t();return n(/^(\))/)?{type:"GeometryCollection",geometries:r}:null}function g(){return a()||c()||l()||s()||f()||p()||d()}var h=e.split(";"),e=h.pop(),v=(h.shift()||"").split("=").pop(),m=0;return r(g())}function t(e){function n(e){return 2===e.length?e[0]+" "+e[1]:3===e.length?e[0]+" "+e[1]+" "+e[2]:void 0}function r(e){return e.map(n).join(", ")}function o(e){return e.map(r).map(u).join(", ")}function i(e){return e.map(o).map(u).join(", ")}function u(e){return"("+e+")"}switch("Feature"===e.type&&(e=e.geometry),e.type){case"Point":return"POINT ("+n(e.coordinates)+")";case"LineString":return"LINESTRING ("+r(e.coordinates)+")";case"Polygon":return"POLYGON ("+o(e.coordinates)+")";case"MultiPoint":return"MULTIPOINT ("+r(e.coordinates)+")";case"MultiPolygon":return"MULTIPOLYGON ("+i(e.coordinates)+")";case"MultiLineString":return"MULTILINESTRING ("+o(e.coordinates)+")";case"GeometryCollection":return"GEOMETRYCOLLECTION ("+e.geometries.map(t).join(", ")+")";default:throw new Error("stringify requires a valid GeoJSON Feature or geometry object as input")}}n.exports=r,n.exports.parse=r,n.exports.stringify=t;var o=/^[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/website/js/nominatim-ui.js b/website/js/nominatim-ui.js index c5e91cf7..25233643 100644 --- a/website/js/nominatim-ui.js +++ b/website/js/nominatim-ui.js @@ -1,6 +1,22 @@ var map; var last_click_latlng; +function parse_and_normalize_geojson_string(raw_string){ + // normalize places the geometry into a featurecollection, similar to + // https://github.com/mapbox/geojson-normalize + var parsed_geojson = { + type: "FeatureCollection", + features: [ + { + type: "Feature", + geometry: JSON.parse(raw_string), + properties: {} + } + ] + }; + return parsed_geojson; +} + jQuery(document).on('ready', function(){ if ( !$('#search-page,#reverse-page').length ){ return; } @@ -159,12 +175,18 @@ jQuery(document).on('ready', function(){ var bounds = [[result.aBoundingBox[0]*1,result.aBoundingBox[2]*1], [result.aBoundingBox[1]*1,result.aBoundingBox[3]*1]]; map.fitBounds(bounds); - if (result.astext && result.astext.match(/(POLY)|(LINE)/) ){ - var geojson_layer = L.geoJson(null, { - // http://leafletjs.com/reference.html#geojson-style - style: function(feature) { return { clickable: false, color: 'blue' }; } - }); - omnivore.wkt.parse(result.astext,null,geojson_layer); + + if (result.asgeojson && result.asgeojson.match(/(Polygon)|(Line)/) ){ + + var geojson_layer = L.geoJson( + parse_and_normalize_geojson_string(result.asgeojson), + { + // http://leafletjs.com/reference-1.0.3.html#path-option + style: function(feature) { + return { interactive: false, color: 'blue' }; + } + } + ); layerGroup.addLayer(geojson_layer); } else { @@ -252,14 +274,18 @@ jQuery(document).on('ready', function(){ var circle = L.circleMarker([nominatim_result.lat,nominatim_result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75}); map.addLayer(circle); - if ( nominatim_result.outlinestring ){ - - var geojson_layer = L.geoJson(null, { - // http://leafletjs.com/reference.html#geojson-style - style: function(feature) { return { clickable: false, color: 'blue' }; } - }); - omnivore.wkt.parse(nominatim_result.outlinestring,null,geojson_layer); - layerGroup.addLayer(geojson_layer); + if ( nominatim_result.asgeojson ){ + + var geojson_layer = L.geoJson( + parse_and_normalize_geojson_string(nominatim_result.asgeojson), + { + // http://leafletjs.com/reference-1.0.3.html#path-option + style: function(feature) { + return { interactive: false, color: 'blue' }; + } + } + ); + map.addLayer(geojson_layer); map.fitBounds(geojson_layer.getBounds()); } else { map.setView([nominatim_result.lat,nominatim_result.lon],10); diff --git a/website/search.php b/website/search.php index 5beb659d..f2f806d6 100755 --- a/website/search.php +++ b/website/search.php @@ -30,8 +30,8 @@ $sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2 // Show / use polygons if ($sOutputFormat == 'html') { - $oGeocode->setIncludePolygonAsText($oParams->getBool('polygon')); - $bAsText = false; + $oGeocode->setIncludePolygonAsGeoJSON($oParams->getBool('polygon_geojson')); + $bAsGeoJSON = false; } else { $bAsPoints = $oParams->getBool('polygon'); $bAsGeoJSON = $oParams->getBool('polygon_geojson'); -- 2.45.1