From 0d4188d40b4d406feb0f9224b39acb93c50e052b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 19 Aug 2018 15:56:28 +0200 Subject: [PATCH] gluon-web-osm: base on OpenLayers 5, add model class The new code is shorter and uses more readable variable names. It does not depend on specifically named input fields anymore (allowing to use multiple maps on the same page), and only uses well-defined interfaces to trigger revalidation of input fields. The Map model class allows to add OSM maps to gluon-web forms. --- .../gluon/config-mode/www/static/gluon.css | 2 +- .../gluon-config-mode-theme/sass/gluon.scss | 6 ++ .../lib/gluon/web/view/model/osm/map.html | 44 ++++++++++ .../lib/gluon/web/www/static/gluon-web-osm.js | 1 + .../files/lib/gluon/web/www/static/osm.js | 1 - .../gluon-web-osm/javascript/gluon-web-osm.js | 84 +++++++++++++++++++ package/gluon-web-osm/javascript/osm.js | 72 ---------------- .../usr/lib/lua/gluon/web/model/osm.lua | 43 ++++++++++ 8 files changed, 179 insertions(+), 74 deletions(-) create mode 100644 package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html create mode 100644 package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js delete mode 100644 package/gluon-web-osm/files/lib/gluon/web/www/static/osm.js create mode 100644 package/gluon-web-osm/javascript/gluon-web-osm.js delete mode 100644 package/gluon-web-osm/javascript/osm.js create mode 100644 package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua diff --git a/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css b/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css index c75fffcd..bbb82a8a 100644 --- a/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css +++ b/package/gluon-config-mode-theme/files/lib/gluon/config-mode/www/static/gluon.css @@ -1 +1 @@ -.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.clear{clear:both}.error{color:#ff0000;background-color:white}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar a:link.topcat,#menubar a:visited.topcat{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link.topcat:hover,#menubar a:link.topcat:focus,#menubar a:visited.topcat:hover,#menubar a:visited.topcat:focus{background:#ffb400;color:black}#menubar a:link.topcat.active,#menubar a:visited.topcat.active{background:#ffb400;color:black;font-weight:bold}#menubar div.hostinfo{position:relative;margin:0;padding:0.5em;flex:1;font-weight:bold;font-size:80%}#menubar div.hostinfo a:link,#menubar div.hostinfo a:visited{text-decoration:none;font-weight:bold;color:white}#menubar div.hostinfo a:link:hover,#menubar div.hostinfo a:link:focus,#menubar div.hostinfo a:visited:hover,#menubar div.hostinfo a:visited:focus{text-decoration:underline}#topmenu{list-style:none;margin:0;padding:0}#topmenu li{display:inline-block}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}#maincontent p{margin-bottom:1em}.gluon-section{margin:0;padding:0;border:none;margin-bottom:1.3em}.gluon-section:last-child{margin-bottom:0.7em}.gluon-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.gluon-section h2{margin:0em 0 0.5em -0.5em !important}.gluon-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.gluon-section-descr{margin-bottom:2em}input:placeholder{color:#aaaaaa}input:-webkit-input-placeholder{color:#aaaaaa}input:-moz-placeholder{color:#aaaaaa}input:-ms-input-placeholder{color:#aaaaaa}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;position:relative;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=radio]{display:none}input[type=radio]+label{display:inline-block;position:relative;width:0.8em;height:0.8em;padding:0.5em;margin:0.2em 0.2em 0.2em 0.1em;border:none;background:#ffe199;vertical-align:middle;border-radius:50%}input[type=radio]:checked+label:after{content:'•';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.4em;width:100%;text-align:center;font-size:2em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em;margin-top:1px;margin-bottom:2px;box-sizing:content-box;outline:0}option{color:#003247;background:#ffe199}input[type=image]{border:none}select,input[type=text],input[type=password]{min-width:20em}input.gluon-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.gluon-button::-moz-focus-inner{padding:0;border:0}input.gluon-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.gluon-button:focus{outline:0}input.gluon-button:hover,input.gluon-button:focus{background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.gluon-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.gluon-button-reset{background-color:#e30;color:#fff}input.gluon-button-submit{background-color:#009ee0;color:#fff}input.gluon-button-submit:active{background:grey}.gluon-input-invalid{background:#e30 !important;color:white}div.gluon-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}.gluon-section .gluon-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.gluon-rowstyle-2{color:#000000}div.gluon-value{display:flex;flex-direction:row;margin-bottom:0.5em}.gluon-section-node .gluon-value:last-child{margin-bottom:0}.gluon-value-title{flex:2;text-align:right;padding-top:0.39em;padding-right:1em;font-weight:bold}div.gluon-value-field{flex:3;position:relative}div.gluon-value-field input,div.gluon-value-field select,div.gluon-value-field input+label{position:relative}div.gluon-value-field-text{flex:3;padding-top:0.39em}div.gluon-value-field-long{flex:10;position:relative;margin-top:0.65em}div.gluon-value-field-long input,div.gluon-value-field-long select,div.gluon-value-field-long input+label{position:relative}div.gluon-value-field-long-after{flex:2}div.gluon-value-description{font-size:8pt}div.gluon-section-create{clear:left;white-space:nowrap;vertical-align:top}div.gluon-section-create .gluon-button{margin:0.25em}input.gluon-section-create-name{margin-right:-0.25em}div.gluon-form-descr{margin-bottom:1em}.gluon-form-descr:empty,.gluon-section-descr:empty{display:none}.gluon-form-descr,.gluon-section-descr,.gluon-page-actions{padding:1em;background:#ececec}.gluon-page-actions{text-align:right;display:flex;flex-flow:row-reverse}div.gluon-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.gluon-section-remove{float:right}.gluon-section-node{clear:both;position:relative;border:none}.gluon-section-node-tabbed{border-top-left-radius:0}div.gluon-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}.gluon-value-error input,.gluon-value-error select{background-color:#ffcccc}.gluon-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.gluon-value-field var{color:#2222FF}.gluon-add:after,.gluon-remove:after{cursor:pointer;display:inline-block;text-align:center;vertical-align:middle;font-size:180%;width:1.2em;height:1em}.gluon-add{color:#008000;position:relative;left:21em}input+.gluon-add{left:0;top:0.04em}.gluon-add:first-child{top:0.53em;left:-0.08em}.gluon-add:after{content:'+'}.gluon-remove{color:#800000;position:relative;top:-0.03em}.gluon-remove:after{content:'–'}.left{text-align:left !important}.right{text-align:right !important}.inline{display:inline}.error500{border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} +.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.clear{clear:both}.error{color:#ff0000;background-color:white}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar a:link.topcat,#menubar a:visited.topcat{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link.topcat:hover,#menubar a:link.topcat:focus,#menubar a:visited.topcat:hover,#menubar a:visited.topcat:focus{background:#ffb400;color:black}#menubar a:link.topcat.active,#menubar a:visited.topcat.active{background:#ffb400;color:black;font-weight:bold}#menubar div.hostinfo{position:relative;margin:0;padding:0.5em;flex:1;font-weight:bold;font-size:80%}#menubar div.hostinfo a:link,#menubar div.hostinfo a:visited{text-decoration:none;font-weight:bold;color:white}#menubar div.hostinfo a:link:hover,#menubar div.hostinfo a:link:focus,#menubar div.hostinfo a:visited:hover,#menubar div.hostinfo a:visited:focus{text-decoration:underline}#topmenu{list-style:none;margin:0;padding:0}#topmenu li{display:inline-block}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}#maincontent p{margin-bottom:1em}.gluon-section{margin:0;padding:0;border:none;margin-bottom:1.3em}.gluon-section:last-child{margin-bottom:0.7em}.gluon-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.gluon-section h2{margin:0em 0 0.5em -0.5em !important}.gluon-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.gluon-section-descr{margin-bottom:2em}.gluon-osm-map{width:100%;height:40em;margin-bottom:1em}input:placeholder{color:#aaaaaa}input:-webkit-input-placeholder{color:#aaaaaa}input:-moz-placeholder{color:#aaaaaa}input:-ms-input-placeholder{color:#aaaaaa}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;position:relative;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=radio]{display:none}input[type=radio]+label{display:inline-block;position:relative;width:0.8em;height:0.8em;padding:0.5em;margin:0.2em 0.2em 0.2em 0.1em;border:none;background:#ffe199;vertical-align:middle;border-radius:50%}input[type=radio]:checked+label:after{content:'•';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.4em;width:100%;text-align:center;font-size:2em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em;margin-top:1px;margin-bottom:2px;box-sizing:content-box;outline:0}option{color:#003247;background:#ffe199}input[type=image]{border:none}select,input[type=text],input[type=password]{min-width:20em}input.gluon-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.gluon-button::-moz-focus-inner{padding:0;border:0}input.gluon-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.gluon-button:focus{outline:0}input.gluon-button:hover,input.gluon-button:focus{background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.gluon-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.gluon-button-reset{background-color:#e30;color:#fff}input.gluon-button-submit{background-color:#009ee0;color:#fff}input.gluon-button-submit:active{background:grey}.gluon-input-invalid{background:#e30 !important;color:white}div.gluon-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}.gluon-section .gluon-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.gluon-rowstyle-2{color:#000000}div.gluon-value{display:flex;flex-direction:row;margin-bottom:0.5em}.gluon-section-node .gluon-value:last-child{margin-bottom:0}.gluon-value-title{flex:2;text-align:right;padding-top:0.39em;padding-right:1em;font-weight:bold}div.gluon-value-field{flex:3;position:relative}div.gluon-value-field input,div.gluon-value-field select,div.gluon-value-field input+label{position:relative}div.gluon-value-field-text{flex:3;padding-top:0.39em}div.gluon-value-field-long{flex:10;position:relative;margin-top:0.65em}div.gluon-value-field-long input,div.gluon-value-field-long select,div.gluon-value-field-long input+label{position:relative}div.gluon-value-field-long-after{flex:2}div.gluon-value-description{font-size:8pt}div.gluon-section-create{clear:left;white-space:nowrap;vertical-align:top}div.gluon-section-create .gluon-button{margin:0.25em}input.gluon-section-create-name{margin-right:-0.25em}div.gluon-form-descr{margin-bottom:1em}.gluon-form-descr:empty,.gluon-section-descr:empty{display:none}.gluon-form-descr,.gluon-section-descr,.gluon-page-actions{padding:1em;background:#ececec}.gluon-page-actions{text-align:right;display:flex;flex-flow:row-reverse}div.gluon-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.gluon-section-remove{float:right}.gluon-section-node{clear:both;position:relative;border:none}.gluon-section-node-tabbed{border-top-left-radius:0}div.gluon-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}.gluon-value-error input,.gluon-value-error select{background-color:#ffcccc}.gluon-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.gluon-value-field var{color:#2222FF}.gluon-add:after,.gluon-remove:after{cursor:pointer;display:inline-block;text-align:center;vertical-align:middle;font-size:180%;width:1.2em;height:1em}.gluon-add{color:#008000;position:relative;left:21em}input+.gluon-add{left:0;top:0.04em}.gluon-add:first-child{top:0.53em;left:-0.08em}.gluon-add:after{content:'+'}.gluon-remove{color:#800000;position:relative;top:-0.03em}.gluon-remove:after{content:'–'}.left{text-align:left !important}.right{text-align:right !important}.inline{display:inline}.error500{border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} diff --git a/package/gluon-config-mode-theme/sass/gluon.scss b/package/gluon-config-mode-theme/sass/gluon.scss index 7d48c354..e534995f 100644 --- a/package/gluon-config-mode-theme/sass/gluon.scss +++ b/package/gluon-config-mode-theme/sass/gluon.scss @@ -284,6 +284,12 @@ code { margin-bottom: 2em; } +.gluon-osm-map { + width: 100%; + height: 40em; + margin-bottom: 1em; +} + input:placeholder { color: #aaaaaa; } diff --git a/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html b/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html new file mode 100644 index 00000000..1a42c510 --- /dev/null +++ b/package/gluon-web-osm/files/lib/gluon/web/view/model/osm/map.html @@ -0,0 +1,44 @@ + + + diff --git a/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js b/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js new file mode 100644 index 00000000..3d85f6f1 --- /dev/null +++ b/package/gluon-web-osm/files/lib/gluon/web/www/static/gluon-web-osm.js @@ -0,0 +1 @@ +"use strict";function initOSM(e,o){var t=document.createElement("link");t.rel="stylesheet",t.type="text/css",t.href=e+"/css/ol.css",document.head.appendChild(t);var n=document.createElement("script"),r=!1;n.onload=n.onreadystatechange=function(){if(!(r||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){r=!0;var t=new Image;t.onload=function(){var e=new ol.style.Style({image:new ol.style.Icon({img:t,imgSize:[30,45],anchor:[.5,1]})}),c=new ol.Feature;c.setStyle(e),o(function(e,t,o,n,r){var a=new ol.Map({target:e,layers:[new ol.layer.Tile({source:new ol.source.OSM}),new ol.layer.Vector({source:new ol.source.Vector({features:[c]})})],view:new ol.View({center:ol.proj.fromLonLat(t),zoom:o})}),l=function(e){c.setGeometry(new ol.geom.Point(e))};return a.addEventListener("click",function(e){l(e.coordinate),r(ol.proj.toLonLat(e.coordinate))}),n&&l(ol.proj.fromLonLat(t)),a})},t.src="data:image/svg+xml,"+escape('')}},n.src=e+"/build/ol.js",document.head.appendChild(n)} \ No newline at end of file diff --git a/package/gluon-web-osm/files/lib/gluon/web/www/static/osm.js b/package/gluon-web-osm/files/lib/gluon/web/www/static/osm.js deleted file mode 100644 index 6ea2ea0e..00000000 --- a/package/gluon-web-osm/files/lib/gluon/web/www/static/osm.js +++ /dev/null @@ -1 +0,0 @@ -function findObj(e){for(list=document.getElementsByClassName("gluon-input-text"),i=0;i' + + '' + + ''; + + var style = document.createElement('link'); + style.rel = 'stylesheet'; + style.type = 'text/css'; + style.href = openlayers_url + '/css/ol.css'; + document.head.appendChild(style); + + var script = document.createElement('script'); + var done = false; + script.onload = script.onreadystatechange = function() { + if (done) + return; + if (this.readyState && this.readyState !== "loaded" && this.readyState !== "complete") + return; + + done = true; + + + var markerImg = new Image(); + markerImg.onload = function() { + var markerStyle = new ol.style.Style({ + image: new ol.style.Icon({ + img: markerImg, + imgSize: [30, 45], + anchor: [0.5, 1] + }) + }); + + var marker = new ol.Feature(); + marker.setStyle(markerStyle); + + ready(function(elMap, pos, zoom, set, onUpdate) { + var map = new ol.Map({ + target: elMap, + layers: [ + new ol.layer.Tile({ + source: new ol.source.OSM() + }), + new ol.layer.Vector({ + source: new ol.source.Vector({ + features: [marker] + }) + }) + ], + view: new ol.View({ + center: ol.proj.fromLonLat(pos), + zoom: zoom, + }) + }); + + var refresh = function(coord) { + marker.setGeometry(new ol.geom.Point(coord)); + } + + map.addEventListener('click', function(e) { + refresh(e.coordinate); + onUpdate(ol.proj.toLonLat(e.coordinate)); + }); + + if (set) + refresh(ol.proj.fromLonLat(pos)); + + return map; + }); + } + + markerImg.src = 'data:image/svg+xml,' + escape(markerSvg); + }; + script.src = openlayers_url + '/build/ol.js'; + document.head.appendChild(script); +} diff --git a/package/gluon-web-osm/javascript/osm.js b/package/gluon-web-osm/javascript/osm.js deleted file mode 100644 index 3aad1f62..00000000 --- a/package/gluon-web-osm/javascript/osm.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - Build using: - - uglifyjs javascript/osm.js -o files/lib/gluon/web/www/static/osm.js -c -m -*/ - -function findObj(name) { - list = document.getElementsByClassName("gluon-input-text"); - for(i = 0; i < list.length; i++) { - item = list.item(i); - if(item.id.indexOf(name) >= 0) return item; - } - return false; -} - -function showMap() { - if ("object" == typeof OpenLayers && false !== findObj("longitude")) { - document.getElementById("locationPickerMap").style.display = "block"; - var e = new OpenLayers.Projection("EPSG:4326"), - a = new OpenLayers.Projection("EPSG:900913"), - t = zoom, - n = new OpenLayers.Layer.Markers("Markers"); - OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, { - defaultHandlerOptions: { - single: !0, - "double": !1, - pixelTolerance: 0, - stopSingle: !1, - stopDouble: !1 - }, - initialize: function() { - this.handlerOptions = OpenLayers.Util.extend({}, this.defaultHandlerOptions), OpenLayers.Control.prototype.initialize.apply(this, arguments), this.handler = new OpenLayers.Handler.Click(this, { - click: this.trigger - }, this.handlerOptions) - }, - trigger: function(t) { - var i = osmMap.getLonLatFromPixel(t.xy); - oLon = findObj("longitude"); - oLat = findObj("latitude"); - lonlat1 = new OpenLayers.LonLat(i.lon, i.lat).transform(a, e), - oLon.value = lonlat1.lon, - oLat.value = lonlat1.lat, - n.clearMarkers(), - n.addMarker(new OpenLayers.Marker(i)), - oLon.className = oLon.className.replace(/ gluon-input-invalid/g, ""), - oLat.className = oLat.className.replace(/ gluon-input-invalid/g, ""); - } - }), osmMap = new OpenLayers.Map("locationPickerMap", { - controls: [new OpenLayers.Control.Navigation, new OpenLayers.Control.PanZoomBar, new OpenLayers.Control.MousePosition], - maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34), - numZoomLevels: 18, - maxResolution: 156543, - units: "m", - projection: a, - displayProjection: e - }); - var i = new OpenLayers.Layer.OSM("OpenStreetMap"); - osmMap.addLayer(i), osmMap.addLayer(n); - var o = longitude, - r = latitude; - oLon = findObj("longitude"); - oLat = findObj("latitude"); - "" != oLon.value && (o = oLon.value), - "" != oLat.value && (r = oLat.value), - n.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(o, r).transform(e, a))); - var l = new OpenLayers.LonLat(o, r), - d = l.transform(e, a); - osmMap.setCenter(d, t); - var s = new OpenLayers.Control.Click; - osmMap.addControl(s), s.activate() - } else setTimeout(showMap, 1e3) -} diff --git a/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua b/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua new file mode 100644 index 00000000..138a5ec8 --- /dev/null +++ b/package/gluon-web-osm/luasrc/usr/lib/lua/gluon/web/model/osm.lua @@ -0,0 +1,43 @@ +module('gluon.web.model.osm', package.seeall) + +local classes = require 'gluon.web.model.classes' +local util = require "gluon.web.util" + +local class = util.class + + +local DEFAULT_URL = 'https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.2.0' + + +MapValue = class(classes.AbstractValue) + +function MapValue:__init__(title, options) + classes.AbstractValue.__init__(self, title) + self.subtemplate = "model/osm/map" + self.openlayers_url = options.openlayers_url or DEFAULT_URL + self.lon = options.lon + self.lat = options.lat + + self.pos = options.pos or {lon = 0, lat = 0} + self.zoom = options.zoom or 0 + self.set = options.set or false +end + +function MapValue:cfgvalue() + local pos_lon = tonumber(self.lon and self.lon:cfgvalue()) + local pos_lat = tonumber(self.lat and self.lat:cfgvalue()) + + if pos_lon and pos_lat then + return { + zoom = 18, + pos = { lon = pos_lon, lat = pos_lat }, + set = true, + } + else + return self + end +end + +function MapValue:validate() + return true +end