diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..c043e5f --- /dev/null +++ b/.eslintrc @@ -0,0 +1,38 @@ +{ + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "env": { + "browser": true, + "es6": true + }, + "extends": "eslint:recommended", + "globals": { + "M": true, + "ol": true, + "CustomEvent": true, + "Handlebars": true, + "proj4": true, + "ActiveXObject": true, + "jsts": true, + "document": true, + "window": true, + "DOMParser": true, + "XMLHttpRequest": true, + "Image": true, + "Draggabilly": true, + "XMLSerializer": true + }, + "rules": { + "import/no-absolute-path": "off", + "no-console":"off", //0 = off, 1 = warn, 2 = error + "no-unused-vars": [ + "error", + { + "vars": "all", + "args": "none" + } + ] + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6067958 --- /dev/null +++ b/LICENSE @@ -0,0 +1,274 @@ +European Union Public Licence +V. 1.2 + +EUPL © the European Union 2007, 2016 + +This European Union Public Licence (the ‘EUPL’) applies to the Work (as +defined below) which is provided under the terms of this Licence. Any use of +the Work, other than as authorised under this Licence is prohibited (to the +extent such use is covered by a right of the copyright holder of the Work). + +The Work is provided under the terms of this Licence when the Licensor (as +defined below) has placed the following notice immediately following the +copyright notice for the Work: “Licensed under the EUPL”, or has expressed by +any other means his willingness to license under the EUPL. + +1. Definitions + +In this Licence, the following terms have the following meaning: +— ‘The Licence’: this Licence. +— ‘The Original Work’: the work or software distributed or communicated by the + ‘Licensor under this Licence, available as Source Code and also as + ‘Executable Code as the case may be. +— ‘Derivative Works’: the works or software that could be created by the + ‘Licensee, based upon the Original Work or modifications thereof. This + ‘Licence does not define the extent of modification or dependence on the + ‘Original Work required in order to classify a work as a Derivative Work; + ‘this extent is determined by copyright law applicable in the country + ‘mentioned in Article 15. +— ‘The Work’: the Original Work or its Derivative Works. +— ‘The Source Code’: the human-readable form of the Work which is the most + convenient for people to study and modify. + +— ‘The Executable Code’: any code which has generally been compiled and which + is meant to be interpreted by a computer as a program. +— ‘The Licensor’: the natural or legal person that distributes or communicates + the Work under the Licence. +— ‘Contributor(s)’: any natural or legal person who modifies the Work under + the Licence, or otherwise contributes to the creation of a Derivative Work. +— ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of + the Work under the terms of the Licence. +— ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, + renting, distributing, communicating, transmitting, or otherwise making + available, online or offline, copies of the Work or providing access to its + essential functionalities at the disposal of any other natural or legal + person. + +2. Scope of the rights granted by the Licence + +The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, +sublicensable licence to do the following, for the duration of copyright +vested in the Original Work: + +— use the Work in any circumstance and for all usage, +— reproduce the Work, +— modify the Work, and make Derivative Works based upon the Work, +— communicate to the public, including the right to make available or display + the Work or copies thereof to the public and perform publicly, as the case + may be, the Work, +— distribute the Work or copies thereof, +— lend and rent the Work or copies thereof, +— sublicense rights in the Work or copies thereof. + +Those rights can be exercised on any media, supports and formats, whether now +known or later invented, as far as the applicable law permits so. + +In the countries where moral rights apply, the Licensor waives his right to +exercise his moral right to the extent allowed by law in order to make +effective the licence of the economic rights here above listed. + +The Licensor grants to the Licensee royalty-free, non-exclusive usage rights +to any patents held by the Licensor, to the extent necessary to make use of +the rights granted on the Work under this Licence. + +3. Communication of the Source Code + +The Licensor may provide the Work either in its Source Code form, or as +Executable Code. If the Work is provided as Executable Code, the Licensor +provides in addition a machine-readable copy of the Source Code of the Work +along with each copy of the Work that the Licensor distributes or indicates, +in a notice following the copyright notice attached to the Work, a repository +where the Source Code is easily and freely accessible for as long as the +Licensor continues to distribute or communicate the Work. + +4. Limitations on copyright + +Nothing in this Licence is intended to deprive the Licensee of the benefits +from any exception or limitation to the exclusive rights of the rights owners +in the Work, of the exhaustion of those rights or of other applicable +limitations thereto. + +5. Obligations of the Licensee + +The grant of the rights mentioned above is subject to some restrictions and +obligations imposed on the Licensee. Those obligations are the following: + +Attribution right: The Licensee shall keep intact all copyright, patent or +trademarks notices and all notices that refer to the Licence and to the +disclaimer of warranties. The Licensee must include a copy of such notices and +a copy of the Licence with every copy of the Work he/she distributes or +communicates. The Licensee must cause any Derivative Work to carry prominent +notices stating that the Work has been modified and the date of modification. + +Copyleft clause: If the Licensee distributes or communicates copies of the +Original Works or Derivative Works, this Distribution or Communication will be +done under the terms of this Licence or of a later version of this Licence +unless the Original Work is expressly distributed only under this version of +the Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee +(becoming Licensor) cannot offer or impose any additional terms or conditions +on the Work or Derivative Work that alter or restrict the terms of the +Licence. + +Compatibility clause: If the Licensee Distributes or Communicates Derivative +Works or copies thereof based upon both the Work and another work licensed +under a Compatible Licence, this Distribution or Communication can be done +under the terms of this Compatible Licence. For the sake of this clause, +‘Compatible Licence’ refers to the licences listed in the appendix attached to +this Licence. Should the Licensee's obligations under the Compatible Licence +conflict with his/her obligations under this Licence, the obligations of the +Compatible Licence shall prevail. + +Provision of Source Code: When distributing or communicating copies of the +Work, the Licensee will provide a machine-readable copy of the Source Code or +indicate a repository where this Source will be easily and freely available +for as long as the Licensee continues to distribute or communicate the Work. + +Legal Protection: This Licence does not grant permission to use the trade +names, trademarks, service marks, or names of the Licensor, except as required +for reasonable and customary use in describing the origin of the Work and +reproducing the content of the copyright notice. + +6. Chain of Authorship + +The original Licensor warrants that the copyright in the Original Work granted +hereunder is owned by him/her or licensed to him/her and that he/she has the +power and authority to grant the Licence. + +Each Contributor warrants that the copyright in the modifications he/she +brings to the Work are owned by him/her or licensed to him/her and that he/she +has the power and authority to grant the Licence. + +Each time You accept the Licence, the original Licensor and subsequent +Contributors grant You a licence to their contributions to the Work, under the +terms of this Licence. + +7. Disclaimer of Warranty + +The Work is a work in progress, which is continuously improved by numerous +Contributors. It is not a finished work and may therefore contain defects or +‘bugs’ inherent to this type of development. + +For the above reason, the Work is provided under the Licence on an ‘as is’ +basis and without warranties of any kind concerning the Work, including +without limitation merchantability, fitness for a particular purpose, absence +of defects or errors, accuracy, non-infringement of intellectual property +rights other than copyright as stated in Article 6 of this Licence. + +This disclaimer of warranty is an essential part of the Licence and a +condition for the grant of any rights to the Work. + +8. Disclaimer of Liability + +Except in the cases of wilful misconduct or damages directly caused to natural +persons, the Licensor will in no event be liable for any direct or indirect, +material or moral, damages of any kind, arising out of the Licence or of the +use of the Work, including without limitation, damages for loss of goodwill, +work stoppage, computer failure or malfunction, loss of data or any commercial +damage, even if the Licensor has been advised of the possibility of such +damage. However, the Licensor will be liable under statutory product liability +laws as far such laws apply to the Work. + +9. Additional agreements + +While distributing the Work, You may choose to conclude an additional +agreement, defining obligations or services consistent with this Licence. +However, if accepting obligations, You may act only on your own behalf and on +your sole responsibility, not on behalf of the original Licensor or any other +Contributor, and only if You agree to indemnify, defend, and hold each +Contributor harmless for any liability incurred by, or claims asserted against +such Contributor by the fact You have accepted any warranty or additional +liability. + +10. Acceptance of the Licence + +The provisions of this Licence can be accepted by clicking on an icon ‘I +agree’ placed under the bottom of a window displaying the text of this Licence +or by affirming consent in any other similar way, in accordance with the rules +of applicable law. Clicking on that icon indicates your clear and irrevocable +acceptance of this Licence and all of its terms and conditions. + +Similarly, you irrevocably accept this Licence and all of its terms and +conditions by exercising any rights granted to You by Article 2 of this +Licence, such as the use of the Work, the creation by You of a Derivative Work +or the Distribution or Communication by You of the Work or copies thereof. + +11. Information to the public + +In case of any Distribution or Communication of the Work by means of +electronic communication by You (for example, by offering to download the Work +from a remote location) the distribution channel or media (for example, a +website) must at least provide to the public the information requested by the +applicable law regarding the Licensor, the Licence and the way it may be +accessible, concluded, stored and reproduced by the Licensee. + +12. Termination of the Licence + +The Licence and the rights granted hereunder will terminate automatically upon +any breach by the Licensee of the terms of the Licence. Such a termination +will not terminate the licences of any person who has received the Work from +the Licensee under the Licence, provided such persons remain in full +compliance with the Licence. + +13. Miscellaneous + +Without prejudice of Article 9 above, the Licence represents the complete +agreement between the Parties as to the Work. + +If any provision of the Licence is invalid or unenforceable under applicable +law, this will not affect the validity or enforceability of the Licence as a +whole. Such provision will be construed or reformed so as necessary to make it +valid and enforceable. + +The European Commission may publish other linguistic versions or new versions +of this Licence or updated versions of the Appendix, so far this is required +and reasonable, without reducing the scope of the rights granted by the +Licence. New versions of the Licence will be published with a unique version +number. + +All linguistic versions of this Licence, approved by the European Commission, +have identical value. Parties can take advantage of the linguistic version of +their choice. + +14. Jurisdiction + +Without prejudice to specific agreement between parties, +— any litigation resulting from the interpretation of this License, arising + between the European Union institutions, bodies, offices or agencies, as a + Licensor, and any Licensee, will be subject to the jurisdiction of the Court + of Justice of the European Union, as laid down in article 272 of the Treaty + on the Functioning of the European Union, +— any litigation arising between other parties and resulting from the + interpretation of this License, will be subject to the exclusive + jurisdiction of the competent court where the Licensor resides or conducts + its primary business. + +15. Applicable Law + +Without prejudice to specific agreement between parties, +— this Licence shall be governed by the law of the European Union Member State + where the Licensor has his seat, resides or has his registered office, +— this licence shall be governed by Belgian law if the Licensor has no seat, + residence or registered office inside a European Union Member State. + +Appendix + +‘Compatible Licences’ according to Article 5 EUPL are: +— GNU General Public License (GPL) v. 2, v. 3 +— GNU Affero General Public License (AGPL) v. 3 +— Open Software License (OSL) v. 2.1, v. 3.0 +— Eclipse Public License (EPL) v. 1.0 +— CeCILL v. 2.0, v. 2.1 +— Mozilla Public Licence (MPL) v. 2 +— GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 +— Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for + works other than software +— European Union Public Licence (EUPL) v. 1.1, v. 1.2 +— Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or + Strong Reciprocity (LiLiQ-R+) + +— The European Commission may update this Appendix to later versions of the + above licences without producing a new version of the EUPL, as long as they + provide the rights granted in Article 2 of this Licence and protect the + covered Source Code from exclusive appropriation. +— All other changes or additions to this Appendix require the production of a + new EUPL version. diff --git a/README.md b/README.md deleted file mode 100644 index 83e0fae..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# mirrorpanel -Mapas sincronizados diff --git a/dist/api.json b/dist/api.json new file mode 100644 index 0000000..53c0a1a --- /dev/null +++ b/dist/api.json @@ -0,0 +1,120 @@ +{ + "url": { + "name": "mirrorpanel", + "separator": "*!" + }, + "constructor": "M.plugin.Mirrorpanel", + "parameters": [ + { + "type": "object", + "properties": [ + { + "type": "simple", + "name": "position", + "possibleValues": [ + "TL", + "TR", + "BL", + "BR" + ], + "position": 0 + }, + { + "type": "boolean", + "name": "collapsed", + "position": 1 + }, + { + "type": "boolean", + "name": "collapsible", + "position": 2 + }, + { + "type": "simple", + "name": "modeViz", + "position": 3 + }, + { + "type": "boolean", + "name": "enabledKeyFunctions", + "position": 4 + }, + { + "type": "boolean", + "name": "showCursors", + "position": 5 + }, + { + "type": "simple", + "name": "mirrorLayers", + "position": 6 + }, + { + "type": "simple", + "name": "defaultBaseLyrs", + "position": 7 + }, + { + "type": "boolean", + "name": "interface", + "position": 8 + }, + { + "type": "boolean", + "name": "showToc", + "position": 9 + } + ] + } + ], + "files": { + "ol": { + "scripts": ["mirrorpanel.ol.min.js"], + "styles": ["mirrorpanel.ol.min.css"] + } + }, + "metadata": { + "uuid_plugin": "", + "uuid_version_plugin": "", + "version_ficha_metadatos": "", + "name": "Mirrorpanel", + "description": "Plugin que permite comparar varias capas dividiendo la pantalla en varias partes.", + "text": "Plugin que permite comparar varias capas dividiendo la pantalla en varias partes. Los mapas tienen sus vistas sincronizadas, y podemos ver la representación de una misma zona por distintas capas.", + "version": "1.0.0", + "date": "Julio, 2020", + "author": "", + "org": "", + "tags": "mapea,plugin", + "icon": "./facade/assets/icons/icons.svg", + "buttons": [ + { + "title": "", + "description": "", + "querySelector": "" + }, + { + "title": "", + "description": "", + "querySelector": "" + } + ], + "dependencies": { + "modules": [ + "", + "" + ], + "plugins": [ + { + "uuid": "", + "name": "" + } + ], + "services": [ + { + "name": "", + "description": "" + } + ] + } + } +} \ No newline at end of file diff --git a/dist/mirrorpanel.ol.min.css b/dist/mirrorpanel.ol.min.css new file mode 100644 index 0000000..9873d82 --- /dev/null +++ b/dist/mirrorpanel.ol.min.css @@ -0,0 +1 @@ +@font-face{font-family:mirrorpanel;src:url(data:application/vnd.ms-fontobject;base64,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);src:url(data:application/vnd.ms-fontobject;base64,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#iefix) format("embedded-opentype"),url(data:font/ttf;base64,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) format("truetype"),url(data:font/woff;base64,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) format("woff"),url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiID4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8bWV0YWRhdGE+R2VuZXJhdGVkIGJ5IEljb01vb248L21ldGFkYXRhPgo8ZGVmcz4KPGZvbnQgaWQ9Im1pcnJvcnBhbmVsIiBob3Jpei1hZHYteD0iMTAyNCI+Cjxmb250LWZhY2UgdW5pdHMtcGVyLWVtPSIxMDI0IiBhc2NlbnQ9Ijg3MC40IiBkZXNjZW50PSItMTUzLjYiIC8+CjxtaXNzaW5nLWdseXBoIGhvcml6LWFkdi14PSIxMDI0IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4MjA7IiBkPSIiIC8+CjxnbHlwaCB1bmljb2RlPSImI3hlODAyOyIgZ2x5cGgtbmFtZT0iaWNvbiIgZD0iTTMyMC41MTIgNTQ0LjUxMmwtMTkyLjUxMi0xOTIuNTEyIDE5Mi41MTItMTkxLjQ4OHYxMjhoMzg0di0xMjhsMTkxLjQ4OCAxOTEuNDg4LTE5MS40ODggMTkyLjUxMnYtMTI4aC0zODR2MTI4ek01MTIgODY0bC01MTItMzE5LjQ4OHYtNzA0LjUxMmw1MTIgMjU2IDUxMi0yNTZ2NzA0LjUxMmwtNTEyIDMxOS40ODh6TTk2MC41MTItMzJsLTM4NCAxOTIuNTEydjYzLjQ4OGgtMTI4di02My40ODhsLTM4NC0xOTIuNTEydjUxMmwzODQgMjU2di0yNTZoMTI4djI1NmwzODQtMjU2di01MTJ6IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4ZTgwMzsiIGdseXBoLW5hbWU9Im1vZGV2aXoxIiBkPSJNMTMyLjkxNCA4NjRjLTczLjEwOSAwLTEzMi44OS01OS43NzQtMTMyLjg5LTEzMi44ODJ2LTc1OC4yN2MwLTczLjEwOCA1OS43NzgtMTMyLjg5IDEzMi44OS0xMzIuODloNzU4LjI4NmM3My4xMDggMCAxMzIuODY1IDU5Ljc4IDEzMi44NjUgMTMyLjg5djc1OC4yN2MwIDczLjEwNi01OS43NTcgMTMyLjg4Mi0xMzIuODY1IDEzMi44ODJ6TTEzMi45MTQgNzk0LjgxOWgzNDYuMzU4di04ODUuNjMzaC0zNDYuMzU4Yy0zNi4wMjMgMC02My43MDEgMjcuNjc4LTYzLjcwMSA2My43MDF2NzU4LjI3YzAgMzYuMDIzIDI3LjY3OCA2My43MDEgNjMuNzAxIDYzLjcwMXpNNTQ0LjgxNyA3OTQuODE5aDM0Ni4zODJjMzYuMDIzIDAgNjMuNjg0LTI3LjY3NSA2My42ODQtNjMuNzAxdi03NTguMjdjMC0zNi4wMjYtMjcuNjYxLTYzLjcwMS02My42ODQtNjMuNzAxaC0zNDYuMzgyeiIgLz4KPGdseXBoIHVuaWNvZGU9IiYjeGU4MDQ7IiBnbHlwaC1uYW1lPSJtb2Rldml6MCIgZD0iTTEzMi45MTQgODY0Yy03My4xMDkgMC0xMzIuODgyLTU5Ljc3My0xMzIuODgyLTEzMi44ODJ2LTc1OC4yN2MwLTczLjEwOSA1OS43NzMtMTMyLjg4MiAxMzIuODgyLTEzMi44ODJoNzU4LjI4NmM3My4xMDkgMCAxMzIuODY1IDU5Ljc3NiAxMzIuODY1IDEzMi44ODJ2NzU4LjI3YzAgNzMuMTA3LTU5Ljc1NiAxMzIuODgyLTEzMi44NjUgMTMyLjg4MnpNMTMyLjkxNCA3OTQuODE1aDc1OC4yODZjMzYuMDIzIDAgNjMuNjgtMjcuNjcgNjMuNjgtNjMuNjk3di03NTguMjdjMC0zNi4wMjYtMjcuNjU3LTYzLjcwMS02My42OC02My43MDFoLTc1OC4yODZjLTM2LjAyMyAwLTYzLjcwMSAyNy42NzgtNjMuNzAxIDYzLjcwMXY3NTguMjdjMCAzNi4wMjMgMjcuNjc4IDYzLjY5NyA2My43MDEgNjMuNjk3eiIgLz4KPGdseXBoIHVuaWNvZGU9IiYjeGU4MDU7IiBnbHlwaC1uYW1lPSJtb2Rldml6MiIgZD0iTTEzMi45MTQgODY0Yy03My4xMDggMC0xMzIuODgyLTU5Ljc3My0xMzIuODgyLTEzMi44ODJ2LTc1OC4yN2MwLTczLjEwOSA1OS43NzQtMTMyLjg5IDEzMi44ODItMTMyLjg5aDc1OC4yODZjNzMuMTA4IDAgMTMyLjg3MyA1OS43OCAxMzIuODczIDEzMi44OXY3NTguMjdjMCA3My4xMDctNTkuNzYyIDEzMi44ODItMTMyLjg3MyAxMzIuODgyek0xMzIuOTE0IDc5NC44MTloMTg2LjYxN3YtODg1LjYzM2gtMTg2LjYxN2MtMzYuMDIzIDAtNjMuNzAxIDI3LjY3OC02My43MDEgNjMuNzAxdjc1OC4yN2MwIDM2LjAyMyAyNy42NzggNjMuNzAxIDYzLjcwMSA2My43MDF6TTM4NS4wNzYgNzk0LjgxOWgyNTMuOTUzdi04ODUuNjMzaC0yNTMuOTUzek03MDQuNTc1IDc5NC44MTloMTg2LjYyNWMzNi4wMjMgMCA2My42ODQtMjcuNjc1IDYzLjY4NC02My43MDF2LTc1OC4yN2MwLTM2LjAyNi0yNy42NjEtNjMuNzAxLTYzLjY4NC02My43MDFoLTE4Ni42MjV6IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4ZTgwNjsiIGdseXBoLW5hbWU9Im1vZGV2aXozIiBkPSJNMTMyLjkxNCA4NjRjLTczLjEwOSAwLTEzMi44ODItNTkuNzc0LTEzMi44ODItMTMyLjg4MnYtNzU4LjI3YzAtNzMuMTA5IDU5Ljc3My0xMzIuODkgMTMyLjg4Mi0xMzIuODloNzU4LjI4NmM3My4xMDkgMCAxMzIuODY1IDU5Ljc4IDEzMi44NjUgMTMyLjg5djc1OC4yN2MwIDczLjEwNy01OS43NTcgMTMyLjg4Mi0xMzIuODY1IDEzMi44ODJ6TTEzMi45MTQgNzk0LjgxOWgxMDYuNzN2LTg4NS42MzNoLTEwNi43M2MtMzYuMDIyIDAtNjMuNjk3IDI3LjY3OC02My42OTcgNjMuNzAxdjc1OC4yN2MwIDM2LjAyMyAyNy42NzQgNjMuNzAxIDYzLjY5NyA2My43MDF6TTMwNS4xOSA3OTQuODE5aDE3NC4wOTF2LTg4NS42MzNoLTE3NC4wOTF6TTU0NC44MjYgNzk0LjgxOWgxNzQuMDgydi04ODUuNjMzaC0xNzQuMDgyek03ODQuNDU0IDc5NC44MTloMTA2Ljc0NmMzNi4wMjMgMCA2My42ODQtMjcuNjc1IDYzLjY4NC02My43MDF2LTc1OC4yN2MwLTM2LjAyNy0yNy42NjItNjMuNzAxLTYzLjY4NC02My43MDFoLTEwNi43NDZ6IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4ZTgwNzsiIGdseXBoLW5hbWU9Im1vZGV2aXo3IiBkPSJNMTMyLjkxNCA4NjRjLTczLjEwOSAwLTEzMi44ODItNTkuNzczLTEzMi44ODItMTMyLjg4MnYtNzU4LjI3YzAtNzMuMTA5IDU5Ljc3NC0xMzIuODgyIDEzMi44ODItMTMyLjg4Mmg3NTguMjg2YzczLjEwOCAwIDEzMi44NjUgNTkuNzc2IDEzMi44NjUgMTMyLjg4MnY3NTguMjdjMCA3My4xMDYtNTkuNzU3IDEzMi44ODItMTMyLjg2NSAxMzIuODgyek0xMzIuOTE0IDc5NC44MTloMzQ2LjM2NnYtODg1LjYzM2gtMzQ2LjM2NmMtMzYuMDIzIDAtNjMuNjk3IDI3LjY3OC02My42OTcgNjMuNzAxdjc1OC4yN2MwIDM2LjAyMyAyNy42NzQgNjMuNzAxIDYzLjY5NyA2My43MDF6TTU0NC44MjYgNzk0LjgxOWgxNzQuMDY2di04ODUuNjMzaC0xNzQuMDY2ek03ODQuNDU0IDc5NC44MTloMTA2Ljc0NmMzNi4wMjMgMCA2My42ODQtMjcuNjc1IDYzLjY4NC02My43MDF2LTc1OC4yN2MwLTM2LjAyNi0yNy42NjEtNjMuNzAxLTYzLjY4NC02My43MDFoLTEwNi43NDZ6IiAvPgo8Z2x5cGggdW5pY29kZT0iJiN4ZTgwODsiIGdseXBoLW5hbWU9Im1vZGV2aXo1IiBkPSJNMTMyLjkxNCA4NjRjLTczLjEwOSAwLTEzMi44OS01OS43NTctMTMyLjg5LTEzMi44NjV2LTc1OC4yODZjMC03My4xMDkgNTkuNzc3LTEzMi44ODIgMTMyLjg5LTEzMi44ODJoNzU4LjI4NmM3My4xMDkgMCAxMzIuODY1IDU5Ljc3NiAxMzIuODY1IDEzMi44ODJ2NzU4LjI4NmMwIDczLjEwNi01OS43NTcgMTMyLjg2NS0xMzIuODY1IDEzMi44NjV6TTEzMi45MTQgNzk0LjgzMWgzNDYuMzY2di00MDkuODUyaC00MTAuMDY0djM0Ni4xNTRjMCAzNi4wMjMgMjcuNjc4IDYzLjY5NyA2My43MDEgNjMuNjk3ek01NDQuODE3IDc5NC44MzFoMzQ2LjM4MmMzNi4wMjMgMCA2My42ODQtMjcuNjcgNjMuNjg0LTYzLjY5N3YtMzQ2LjE1NGgtNDEwLjA2NHpNNjkuMjA4IDMxOS4wMDJoNDEwLjA2NHYtNDA5Ljg2aC0zNDYuMzU4Yy0zNi4wMjMgMC02My43MDEgMjcuNjc0LTYzLjcwMSA2My42OTd6TTU0NC44MTcgMzE5LjAwMmg0MTAuMDY0di0zNDYuMTYzYzAtMzYuMDI3LTI3LjY2Mi02My42OTctNjMuNjg0LTYzLjY5N2gtMzQ2LjM4MnoiIC8+CjxnbHlwaCB1bmljb2RlPSImI3hlODA5OyIgZ2x5cGgtbmFtZT0ibW9kZXZpejgiIGQ9Ik0xMzIuOTE0IDg2NGMtNzMuMTA5IDAtMTMyLjg4Mi01OS43NzctMTMyLjg4Mi0xMzIuODl2LTc1OC4yN2MwLTczLjEwOSA1OS43NzQtMTMyLjg4MiAxMzIuODgyLTEzMi44ODJoNzU4LjI4NmM3My4xMDggMCAxMzIuODczIDU5Ljc3NiAxMzIuODczIDEzMi44ODJ2NzU4LjI3YzAgNzMuMTA3LTU5Ljc2MSAxMzIuODktMTMyLjg3MyAxMzIuODl6TTEzMi45MTQgNzk0LjgxNWg3NTguMjg2YzM2LjAyMyAwIDYzLjY4NC0yNy42NzQgNjMuNjg0LTYzLjcwMXYtMzQ2LjEzOGgtODg1LjYzM3YzNDYuMTM4YzAgMzYuMDIzIDI3LjY3OCA2My43MDEgNjMuNzAxIDYzLjcwMXpNNjkuMjEzIDMxOS4wMDJoNDEwLjA2NHYtNDA5Ljg2aC0zNDYuMzY2Yy0zNi4wMjMgMC02My43MDEgMjcuNjc4LTYzLjcwMSA2My43MDF6TTU0NC44MjIgMzE5LjAwMmg0MTAuMDY0di0zNDYuMTU0YzAtMzYuMDI2LTI3LjY2MS02My43MDEtNjMuNjg0LTYzLjcwMWgtMzQ2LjM4MnoiIC8+CjwvZm9udD48L2RlZnM+PC9zdmc+#mirrorpanel) format("svg");font-weight:400;font-style:normal;font-display:block}.info{position:absolute;width:60%;padding:5px;top:10px;left:20%;background:hsla(0,0%,96.1%,.8);font-size:large;border-radius:5px;border-style:dashed;border-width:2px;text-align:center}.m-panel-btn.mirrorpanel-icon{color:#718bd3!important}.m-plugin-panelMirrorpanel.hidden{display:none}div.m-plugin-panelMirrorpanel.opened>.m-panel-btn.g-cartografia-flecha-derecha,div.m-plugin-panelMirrorpanel.opened>.m-panel-btn.g-cartografia-flecha-izquierda{color:#e8f5e9!important}.m-plugin-panelMirrorpanel.collapsed>div.m-panel-controls{display:none!important}div.m-plugin-panelMirrorpanel.opened{min-width:max-content}.m-areas>div.m-area.m-right>div.m-plugin-panelMirrorpanel.opened>button.m-panel-btn{position:absolute;left:-2.5rem;background-color:#718bd3}.m-areas>div.m-area.m-left>div.m-plugin-panelMirrorpanel.opened>button.m-panel-btn{position:absolute;right:-2.5rem;left:unset!important;background-color:#718bd3}.div-m-mirrorpanel-panel{padding:.7rem}.m-mirrorpanel-effect-buttoms{padding:.3rem 0;text-align:center}div#m-mirrorpanel-titulo{display:block;font-size:15px;height:40px;line-height:40px;padding:0 .3rem;text-align:center;border-radius:4px 4px 0 0;border-bottom:1.5px solid rgba(0,0,0,.12)}.m-mirrorpanel-container .big-button{font-size:32px;background:none;border:none;cursor:pointer;opacity:.75;transition:all .25s ease;color:#404040;outline:none}.m-mirrorpanel-container .big-button:hover,.m-mirrorpanel-container .buttom-pressed{color:#718bd3}[class*=" mirrorpanel-"],[class^=mirrorpanel-]{font-family:mirrorpanel!important;speak:never;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}[class*=" mirrorpanel-"]:before,[class^=mirrorpanel-]:before{display:block}.mirrorpanel-icon:before{content:"\e802";font-family:mirrorpanel!important}.mirrorpanel-modeviz0:before{content:"\e804"}.mirrorpanel-modeviz1:before{content:"\e803"}.mirrorpanel-modeviz2:before{content:"\e803";transform:rotate(90deg)}.mirrorpanel-modeviz3:before{content:"\e805"}.mirrorpanel-modeviz4:before{content:"\e806"}.mirrorpanel-modeviz5:before{content:"\e808"}.mirrorpanel-modeviz6:before{content:"\e806";transform:rotate(90deg)}.mirrorpanel-modeviz7:before{content:"\e807"}.mirrorpanel-modeviz8:before{content:"\e809"}.mirrorpanel-modeviz9:before{content:"\e809";transform:rotate(180deg)}.mirrorpanel-grid{display:grid;height:100%;width:100%;margin:0;padding:0;grid-template-columns:1fr;grid-template-rows:1fr;gap:1px 1px;grid-template-areas:mirror1}.mirrorpanel-grid .mirror1,.mirrorpanel-grid .mirror2,.mirrorpanel-grid .mirror3,.mirrorpanel-grid .mirror4{display:none;min-height:100%}.mirrorpanel-grid .mirror1,.mirrorpanel-grid.modeViz4 .mirror4,.mirrorpanel-grid.modeViz5 .mirror4,.mirrorpanel-grid.modeViz6 .mirror4,.mirrorpanel-grid:not(.modeViz0) .mirror2,.mirrorpanel-grid:not(.modeViz0):not(.modeViz1):not(.modeViz2) .mirror3{display:block!important}.mirror1{grid-area:mirror1}.mirror2{grid-area:mirror2}.mirror3{grid-area:mirror3}.mirror4{grid-area:mirror4}.mirrorpanel-grid.modeViz0{grid-template-columns:1fr!important;grid-template-rows:1fr!important;grid-template-areas:"mirror1"!important}.mirrorpanel-grid.modeViz1{grid-template-columns:1fr 1fr!important;grid-template-rows:1fr!important;grid-template-areas:"mirror1 mirror2"!important}.mirrorpanel-grid.modeViz2{grid-template-columns:1fr!important;grid-template-rows:1fr 1fr!important;grid-template-areas:"mirror1" "mirror2"!important}.mirrorpanel-grid.modeViz3{grid-template-columns:1fr 1fr 1fr!important;grid-template-rows:1fr!important;grid-template-areas:"mirror1 mirror2 mirror3"!important}.mirrorpanel-grid.modeViz4{grid-template-columns:1fr 1fr 1fr 1fr!important;grid-template-rows:1fr!important;grid-template-areas:"mirror1 mirror2 mirror3 mirror4"!important}.mirrorpanel-grid.modeViz5{grid-template-columns:1fr 1fr!important;grid-template-rows:1fr 1fr!important;grid-template-areas:"mirror1 mirror2" "mirror3 mirror4"!important}.mirrorpanel-grid.modeViz6{grid-template-columns:1fr!important;grid-auto-rows:1fr 1fr 1fr 1fr!important;grid-template-areas:"mirror1" "mirror2" "mirror3" "mirror4"!important}.mirrorpanel-grid.modeViz7{grid-template-columns:2fr 1fr 1fr!important;grid-template-rows:1fr!important;grid-template-areas:"mirror1 mirror2 mirror3"!important}.mirrorpanel-grid.modeViz8{grid-template-areas:"mirror1 mirror1" "mirror2 mirror3"!important}.mirrorpanel-grid.modeViz8,.mirrorpanel-grid.modeViz9{grid-template-columns:1fr 1fr!important;grid-template-rows:1fr 1fr!important}.mirrorpanel-grid.modeViz9{grid-template-areas:"mirror1 mirror2" "mirror3 mirror3"!important} \ No newline at end of file diff --git a/dist/mirrorpanel.ol.min.js b/dist/mirrorpanel.ol.min.js new file mode 100644 index 0000000..54d1fe4 --- /dev/null +++ b/dist/mirrorpanel.ol.min.js @@ -0,0 +1,2 @@ +!function(t){var e={};function o(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=t,o.c=e,o.d=function(t,e,r){o.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},o.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(o.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)o.d(r,n,function(e){return t[e]}.bind(null,n));return r},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,"a",e),e},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o.p="",o(o.s=5)}([function(t,e){t.exports='
\r\n
{{translations.title}}
\r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n\r\n
\r\n'},function(t){t.exports=JSON.parse('{"tooltip":"Mirror Comparison","title":"Mirror Maps","modViz0":"Standard map","modViz1":"Vertical two maps","modViz2":"Horizontal two maps","modViz3":"Vertical three maps","modViz4":"Vertical four maps","modViz5":"Mosaic maps","modViz6":"Horizontal four maps","modViz7":"Vertical 2-1-1 proportional maps","modViz8":"One map above and two below","modViz9":"Two maps above and one below"}')},function(t){t.exports=JSON.parse('{"tooltip":"Comparador de mapas espejo","title":"Mapas espejo","modViz0":"Mapa standard","modViz1":"Dos mapas en vertical","modViz2":"Dos mapas en horizontal","modViz3":"Tres mapas en vertical","modViz4":"Cuatro mapas en vertical","modViz5":"Mosaico de mapas","modViz6":"Cuatro mapas en horizontal","modViz7":"Tres mapas en proporción 2-1-1","modViz8":"Un mapa arriba y dos abajo","modViz9":"Dos mapas arriba y uno abajo"}')},function(t){t.exports=JSON.parse('{"url":{"name":"mirrorpanel","separator":"*!"},"constructor":"M.plugin.Mirrorpanel","parameters":[{"type":"object","properties":[{"type":"simple","name":"position","possibleValues":["TL","TR","BL","BR"],"position":0},{"type":"boolean","name":"collapsed","position":1},{"type":"boolean","name":"collapsible","position":2},{"type":"simple","name":"modeViz","position":3},{"type":"boolean","name":"enabledKeyFunctions","position":4},{"type":"boolean","name":"showCursors","position":5},{"type":"simple","name":"mirrorLayers","position":6},{"type":"simple","name":"defaultBaseLyrs","position":7},{"type":"boolean","name":"interface","position":8},{"type":"boolean","name":"showToc","position":9}]}],"files":{"ol":{"scripts":["mirrorpanel.ol.min.js"],"styles":["mirrorpanel.ol.min.css"]}},"metadata":{"uuid_plugin":"","uuid_version_plugin":"","version_ficha_metadatos":"","name":"Mirrorpanel","description":"Plugin que permite comparar varias capas dividiendo la pantalla en varias partes.","text":"Plugin que permite comparar varias capas dividiendo la pantalla en varias partes. Los mapas tienen sus vistas sincronizadas, y podemos ver la representación de una misma zona por distintas capas.","version":"1.0.0","date":"Julio, 2020","author":"","org":"","tags":"mapea,plugin","icon":"./facade/assets/icons/icons.svg","buttons":[{"title":"","description":"","querySelector":""},{"title":"","description":"","querySelector":""}],"dependencies":{"modules":["",""],"plugins":[{"uuid":"","name":""}],"services":[{"name":"","description":""}]}}}')},function(t,e,o){},function(t,e,o){"use strict";o.r(e);o(4);function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var o=0;o1&&void 0!==arguments[1]?arguments[1]:y(),o=h(e),r="";return M.utils.isNullOrEmpty(o)?console.warn("The translation '".concat(e,"' has not been defined.")):r=t.split(".").reduce((function(t,e){return t[e]}),o),r};function v(t){return(v="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function g(t,e){for(var o=0;o0&&(this.mapL.A.addLayers(this.mirrorLayers),this.mapL.A.getLayers().forEach((function(t){0!==t.zindex_&&t.setVisible(!1)}))),this.showCursors&&this.addLayerCursor("A"),new Promise((function(t,o){var r;r={jsonp:!0,vars:{translations:{title:b("title"),modViz0:b("modViz0"),modViz1:b("modViz1"),modViz2:b("modViz2"),modViz3:b("modViz3"),modViz4:b("modViz4"),modViz5:b("modViz5"),modViz6:b("modViz6"),modViz7:b("modViz7"),modViz8:b("modViz8"),modViz9:b("modViz9")}}},e.template=M.template.compileSync(d.a,r),e.template.querySelectorAll('button[id^="set-mirror-"]').forEach((function(t,o){t.addEventListener("click",(function(t){e.manageVisionPanelByCSSGrid(o)}))})),e.manageVisionPanelByCSSGrid(e.modeViz),t(e.template)}))}},{key:"activate",value:function(){L(V(i.prototype),"activate",this).call(this)}},{key:"deactivate",value:function(){L(V(i.prototype),"deactivate",this).call(this)}},{key:"createMapContainers",value:function(){var t=document.createElement("div");t.id="lienzo",t.classList.add("mirrorpanel-grid");var e=document.getElementById("mapjs")||document.getElementById("map");document.body.insertBefore(t,e),e.classList.add("mirror1"),t.appendChild(e);var o=document.createElement("div");o.id="mapjsB",o.classList.add("mirror2"),t.appendChild(o);var r=document.createElement("div");r.id="mapjsC",r.classList.add("mirror3"),t.appendChild(r);var n=document.createElement("div");n.id="mapjsD",n.classList.add("mirror4"),t.appendChild(n)}},{key:"manageVisionPanelByCSSGrid",value:function(t){var e=this.modeViz;(document.getElementById("mapjs")||document.getElementById("map")).style.display="none",document.getElementById("mapjsB").style.display="none",document.getElementById("mapjsC").style.display="none",document.getElementById("mapjsD").style.display="none",this.template.querySelector("#set-mirror-"+e).classList.remove("buttom-pressed");for(var o=0;o<10;o++)document.getElementById("lienzo").classList.remove("modeViz"+o);document.getElementById("lienzo").classList.add("modeViz"+t),[1,2].includes(t)&&null==this.mapL.B&&this.createMapObjects("B"),[3,7,8,9].includes(t)&&(null==this.mapL.B&&this.createMapObjects("B"),null==this.mapL.C&&this.createMapObjects("C")),[4,5,6].includes(t)&&(null==this.mapL.B&&this.createMapObjects("B"),null==this.mapL.C&&this.createMapObjects("C"),null==this.mapL.D&&this.createMapObjects("D")),this.modeViz=t,this.template.querySelector("#set-mirror-"+t).classList.add("buttom-pressed"),this.map_.refresh(),null!==this.mapL.B&&this.mapL.B.refresh(),null!==this.mapL.C&&this.mapL.C.refresh(),null!==this.mapL.D&&this.mapL.D.refresh()}},{key:"createMapObjects",value:function(t){var e=null;switch(t){case"B":this.defaultBaseLyrs[1]&&(e=this.defaultBaseLyrs[0]);break;case"C":this.defaultBaseLyrs[2]&&(e=this.defaultBaseLyrs[1]);break;case"D":this.defaultBaseLyrs[3]&&(e=this.defaultBaseLyrs[2]);break;default:e=this.map_.getLayers()[0].setMap(this)}this.mapL[t]=M.map({container:"mapjs"+t,layers:e,controls:this.showTOC?["layerswitcher"]:"",center:this.map_.getCenter(),projection:this.map_.getProjection().code+"*"+this.map_.getProjection().units,zoom:this.map_.getZoom()}),this.mapL[t].getMapImpl().setView(this.map_.getMapImpl().getView()),this.showCursors&&this.addLayerCursor(t),this.mirrorLayers.length>0&&(this.mapL[t].addLayers(this.mirrorLayers),this.mapL[t].getLayers().forEach((function(t){0!==t.zindex_&&t.setVisible(!1)}))),this.mapL[t].refresh()}},{key:"addLayerCursor",value:function(t){var e=this;this.lyrCursor[t]=new M.layer.Vector({name:"Coordenadas centro "+t},{displayInLayerSwitcher:!1}),this.featureLyrCursor[t]=new M.Feature("Center"+t,{type:"Feature",properties:{},geometry:{type:"Point",coordinates:this.mapL[t].getCenter()}}),this.lyrCursor[t].addFeatures([this.featureLyrCursor[t]]),this.lyrCursor[t].setStyle(this.styleCursor),this.lyrCursor[t].setZIndex(5e3),this.mapL[t].addLayers(this.lyrCursor[t]),this.mapL[t].getMapImpl().on("pointermove",(function(o){e.lyrCursor[t].setVisible(!1),Object.keys(e.featureLyrCursor).forEach((function(r){e.mapL[r]&&e.mapL[r].getMapImpl().setView(e.mapL[t].getMapImpl().getView()),r!=t&&null!==e.featureLyrCursor[r]&&(e.lyrCursor[r].setVisible(!0),e.featureLyrCursor[r].setGeometry({type:"Point",coordinates:o.coordinate}))}))}))}},{key:"removeMaps",value:function(){this.mapL.B=null,this.mapL.C=null,this.mapL.D=null}},{key:"destroyMapsContainer",value:function(){document.getElementById("mapjsB").remove(),document.getElementById("mapjsC").remove(),document.getElementById("mapjsD").remove();var t=document.getElementById("lienzo"),e=document.getElementById("mapjs")||document.getElementById("map");e.style.display="block",e.classList.remove("mirror1"),document.body.insertBefore(e,t),document.getElementById("lienzo").remove()}},{key:"equals",value:function(t){return t instanceof i}}])&&g(e.prototype,o),r&&g(e,r),i}(),O=o(3);function B(t){return(B="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function j(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function S(t,e){for(var o=0;o0&&void 0!==arguments[0]?arguments[0]:{};j(this,i),(t=n.call(this)).name_="mirrorpanel",t.map_=null,t.controls_=[],t.className="m-plugin-mirrorpanel";var o=["TR","TL","BL","BR"];return t.position=o.includes(e.position)?e.position:"TR",t.collapsed=e.collapsed,void 0===t.collapsed&&(t.collapsed=!0),t.collapsible=e.collapsible,void 0===t.collapsible&&(t.collapsible=!0),t.modeViz=e.modeViz,void 0===t.modeViz&&(t.modeViz=0),t.enabledKeyFunctions=e.enabledKeyFunctions,void 0===t.enabledKeyFunctions&&(t.enabledKeyFunctions=!0),t.showCursors=e.showCursors,void 0===t.showCursors&&(t.showCursors=!0),t.mirrorLayers=[],void 0!==e.mirrorLayers&&(Array.isArray(e.mirrorLayers)?t.mirrorLayers=e.mirrorLayers:t.mirrorLayers=e.mirrorLayers.split(",")),t.defaultBaseLyrs=[],void 0!==e.defaultBaseLyrs&&(Array.isArray(e.defaultBaseLyrs)?t.defaultBaseLyrs=e.defaultBaseLyrs:t.defaultBaseLyrs=e.defaultBaseLyrs.split(",")),t.interface=void 0===e.interface||e.interface,t.showTOC=e.showTOC,void 0===t.showTOC&&(t.showTOC=!0),t.tooltip_=e.tooltip||b("tooltip"),t.metadata_=O.metadata,t}return e=i,(o=[{key:"addTo",value:function(t){var e=this,o={pluginOnLeft:!!["TL","BL"].includes(this.position),collapsible:this.collapsible,collapsed:this.collapsed,modeViz:this.modeViz,showCursors:this.showCursors,mirrorLayers:this.mirrorLayers,defaultBaseLyrs:this.defaultBaseLyrs,showTOC:this.showTOC};this.control_=new _(o),this.controls_.push(this.control_),this.map_=t,this.panel_=new M.ui.Panel("panelMirrorpanel",{collapsible:this.collapsible,collapsed:this.collapsed,position:M.ui.position[this.position],modeViz:this.modeViz,showCursors:this.showCursors,className:this.interface?"m-plugin-panelMirrorpanel":"m-plugin-panelMirrorpanel hidden",collapsedButtonClass:"mirrorpanel-icon",tooltip:this.tooltip_}),this.panel_.addControls(this.controls_),t.addPanels(this.panel_),document.addEventListener("keydown",(function(t){if(e.enabledKeyFunctions){for(var o=0;o<10;o++)t.ctrlKey&&t.shiftKey&&t.key==="F"+(o+1)&&e.control_.manageVisionPanelByCSSGrid(o);var r=["Control","Shift","Alt","Meta"].includes(t.key)?"":t.key;"Escape"==(t.ctrlKey?"Control ":"")+(t.shiftKey?"Shift ":"")+(t.altKey?"Alt ":"")+(t.metaKey?"Meta ":"")+r&&e.control_.manageVisionPanelByCSSGrid(0)}}))}},{key:"destroy",value:function(){document.removeEventListener("keydown",(function(t){})),this.control_.removeMaps(),this.control_.destroyMapsContainer(),this.map_.removeControls([this.control_]);var t=[null,null,null,null,null,null,null,null,null,null,null,null];this.control_=t[0],this.panel_=t[1],this.map_=t[2],this.collapsible=t[3],this.collapsed=t[4],this.modeViz=t[5],this.enabledKeyFunctions=t[6],this.showCursors=t[7],this.mirrorLayers=t[8],this.defaultBaseLyrs=t[9],this.interface=t[10],this.showTOC=t[11]}},{key:"getMetadata",value:function(){return this.metadata_}},{key:"getAPIRest",value:function(){return"".concat(this.name,"=").concat(this.position,"*!").concat(this.collapsed,"*!").concat(this.collapsible,"*!").concat(this.modeViz,"*!").concat(this.enabledKeyFunctions,"*!").concat(this.showCursors,"*!").concat(this.mirrorLayers,"*!").concat(this.defaultBaseLyrs,"*!").concat(this.interface,"*!").concat(this.showTOC)}},{key:"activate",value:function(){this.control_.activate()}},{key:"deactivate",value:function(){this.control_.deactivate()}},{key:"name",get:function(){return this.name_}}])&&S(e.prototype,o),r&&S(e,r),i}();window.M.plugin||(window.M.plugin={}),window.M.control||(window.M.control={}),window.M.impl||(window.M.impl={}),window.M.impl.control||(window.M.impl.control={}),window.M.plugin.Mirrorpanel=R,window.M.control.MirrorpanelControl=_,window.M.impl.control.MirrorpanelControl=p}]); +//# sourceMappingURL=mirrorpanel.ol.min.js.map \ No newline at end of file diff --git a/dist/mirrorpanel.ol.min.js.map b/dist/mirrorpanel.ol.min.js.map new file mode 100644 index 0000000..b18c62d --- /dev/null +++ b/dist/mirrorpanel.ol.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/templates/mirrorpanel.html","webpack:///./src/impl/ol/js/mirrorpanelcontrol.js","webpack:///./src/facade/js/i18n/language.js","webpack:///./src/facade/js/mirrorpanelcontrol.js","webpack:///./src/facade/js/mirrorpanel.js","webpack:///./src/index.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","MirrorpanelControl","M","impl","Control","map","html","getMapImpl","getInteractions","forEach","interaction","ol","DoubleClickZoom","dblClickInteraction_","translations","en","es","getLang","res","language","getTranslation","lang","getValue","keyPath","translation","utils","isNullOrEmpty","console","warn","split","reduce","prev","current","values","isUndefined","MirrorpanelImplControl","exception","template","modeViz","showCursors","mapL","A","B","C","D","lyrCursor","featureLyrCursor","styleCursor","style","Point","icon","form","CIRCLE","fontsize","radius","rotation","rotate","offset","color","fill","gradientcolor","opacity","defaultBaseLyrs","mirrorLayers","showTOC","createMapContainers","compileSync","string","options","parseToHtml","templateVars","vars","htmlText","Handlebars","compile","templateFn","stringToHtml","this","length","addLayers","getLayers","zindex_","setVisible","addLayerCursor","Promise","success","fail","templateOptions","jsonp","title","getValueTranslate","modViz0","modViz1","modViz2","modViz3","modViz4","modViz5","modViz6","modViz7","modViz8","modViz9","querySelectorAll","button","addEventListener","evt","manageVisionPanelByCSSGrid","bigContainer","document","createElement","id","classList","add","mapjsA","getElementById","body","insertBefore","appendChild","mapjsB","mapjsC","mapjsD","oldModeViz","display","querySelector","remove","includes","createMapObjects","map_","refresh","mapLyr","defLyr","setMap","container","layers","controls","center","getCenter","projection","getProjection","code","units","zoom","getZoom","setView","getView","layer","Vector","displayInLayerSwitcher","Feature","type","properties","geometry","coordinates","addFeatures","setStyle","setZIndex","on","event","keys","k","setGeometry","coordinate","lienzo","control","Mirrorpanel","Plugin","name_","controls_","className","positions","position","collapsed","undefined","collapsible","enabledKeyFunctions","Array","isArray","tooltip_","tooltip","metadata_","api","metadata","pluginOnLeft","control_","push","panel_","ui","Panel","collapsedButtonClass","addControls","addPanels","zEvent","ctrlKey","shiftKey","keyStr","altKey","metaKey","removeEventListener","removeMaps","destroyMapsContainer","removeControls","activate","deactivate","window","plugin","M$plugin$Mirrorpanel","M$control$MirrorpanelControl","M$impl$control$MirrorpanelControl"],"mappings":"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","file":"mirrorpanel.ol.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 5);\n","module.exports = \"
\\r\\n
{{translations.title}}
\\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n
\\r\\n
\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n
\\r\\n \\r\\n
\\r\\n\\r\\n
\\r\\n\";","/**\r\n * @module M/impl/control/MirrorpanelControl\r\n */\r\nexport default class MirrorpanelControl extends M.impl.Control {\r\n /**\r\n * This function adds the control to the specified map\r\n *\r\n * @public\r\n * @function\r\n * @param {M.Map} map to add the plugin\r\n * @param {HTMLElement} html of the plugin\r\n * @api stable\r\n */\r\n addTo(map, html) {\r\n // obtengo la interacción por defecto del dblclick para manejarla\r\n const olMap = map.getMapImpl();\r\n olMap.getInteractions().forEach((interaction) => {\r\n if (interaction instanceof ol.interaction.DoubleClickZoom) {\r\n this.dblClickInteraction_ = interaction;\r\n }\r\n });\r\n super.addTo(map, html);\r\n }\r\n}\r\n","import en from './en';\nimport es from './es';\n\n/**\n * Default object with es and en translate.\n *\n * @const\n * @type {object}\n */\nconst translations = {\n en,\n es,\n};\n\nconst getLang = () => {\n let res = 'es';\n if (typeof M.language.getLang === 'function') {\n res = M.language.getLang();\n }\n\n return res;\n};\n\n/**\n * This function sets a new language translate.\n * @param {string} lang\n * @param {JSON} json\n * @public\n * @api\n */\nexport const addTranslation = (lang, json) => {\n translations[lang] = json;\n};\n\n/**\n * This function gets a language translate.\n *\n * @param {string} lang\n * @return {JSON}\n * @public\n * @api\n */\nexport const getTranslation = (lang) => {\n return translations[lang];\n};\n\n/**\n * This function gets a language value from key\n *\n * @public\n * @param {string}\n * @param {string}\n * @return {string}\n * @public\n * @api\n */\n\nexport const getValue = (keyPath, lang = getLang()) => {\n const translation = getTranslation(lang);\n let value = '';\n if (M.utils.isNullOrEmpty(translation)) {\n /* eslint-disable no-console */\n console.warn(`The translation '${lang}' has not been defined.`);\n } else {\n value = keyPath.split('.').reduce((prev, current) => prev[current], translation);\n }\n\n return value;\n};\n","/**\r\n * @module M/control/MirrorpanelControl\r\n */\r\n\r\nimport MirrorpanelImplControl from 'impl/mirrorpanelcontrol';\r\nimport template from 'templates/mirrorpanel';\r\nimport { getValue as getValueTranslate } from './i18n/language';\r\n\r\nexport default class MirrorpanelControl extends M.Control {\r\n /**\r\n * @classdesc\r\n * Main constructor of the class. Creates a PluginControl\r\n * control\r\n *\r\n * @constructor\r\n * @extends {M.Control}\r\n * @api stable\r\n */\r\n constructor(values) {\r\n // 1. checks if the implementation can create PluginControl\r\n if (M.utils.isUndefined(MirrorpanelImplControl)) {\r\n M.exception('La implementación usada no puede crear controles MirrorpanelControl');\r\n }\r\n // 2. implementation of this control\r\n const impl = new MirrorpanelImplControl();\r\n super(impl, 'Mirrorpanel');\r\n\r\n /**\r\n * Template\r\n * @public\r\n * @type { HTMLElement }\r\n */\r\n this.template = null;\r\n\r\n /**\r\n * Visual mode\r\n * @private\r\n * @type {Number}\r\n */\r\n this.modeViz = values.modeViz;\r\n\r\n /**\r\n * Mirror maps with plugins\r\n * @private\r\n * @type {boolean}\r\n */\r\n this.showCursors = values.showCursors;\r\n\r\n /**\r\n * Defining mirror maps variables\r\n */\r\n this.mapL = {\r\n A: null,\r\n B: null,\r\n C: null,\r\n D: null,\r\n }\r\n this.lyrCursor = {\r\n A: null,\r\n B: null,\r\n C: null,\r\n D: null,\r\n }\r\n this.featureLyrCursor = {\r\n A: null,\r\n B: null,\r\n C: null,\r\n D: null,\r\n }\r\n\r\n /**\r\n * Defining cursor style\r\n */\r\n this.styleCursor = new M.style.Point({\r\n icon: {\r\n form: M.style.form.CIRCLE,\r\n fontsize: 0.5,\r\n radius: 5,\r\n rotation: 0,\r\n rotate: false,\r\n offset: [0, 0],\r\n color: 'black',\r\n fill: 'red',\r\n gradientcolor: '#088A85',\r\n opacity: 0.8\r\n }\r\n });\r\n\r\n /**\r\n * Default layers for mirror maps\r\n * @public\r\n * @public {Array}\r\n */\r\n this.defaultBaseLyrs = values.defaultBaseLyrs;\r\n\r\n /**\r\n * All layers\r\n * @public\r\n * @public {Array}\r\n */\r\n this.mirrorLayers = values.mirrorLayers;\r\n\r\n /**\r\n * Enable layerswitcher control\r\n * @public\r\n * @public {Array}\r\n */\r\n this.showTOC = values.showTOC;\r\n\r\n this.createMapContainers();\r\n }\r\n\r\n\r\n /**\r\n * This function creates the view\r\n *\r\n * @public\r\n * @function\r\n * @param {M.Map} map to add the control\r\n * @api stable\r\n */\r\n createView(map) {\r\n if (!M.template.compileSync) {\r\n M.template.compileSync = (string, options) => {\r\n let templateCompiled;\r\n let templateVars = {};\r\n let parseToHtml;\r\n if (!M.utils.isUndefined(options)) {\r\n templateVars = M.utils.extends(templateVars, options.vars);\r\n parseToHtml = options.parseToHtml;\r\n }\r\n const templateFn = Handlebars.compile(string);\r\n const htmlText = templateFn(templateVars);\r\n if (parseToHtml !== false) {\r\n templateCompiled = M.utils.stringToHtml(htmlText);\r\n } else {\r\n templateCompiled = htmlText;\r\n }\r\n return templateCompiled;\r\n };\r\n }\r\n\r\n this.mapL['A'] = map;\r\n if (this.mirrorLayers.length > 0) {\r\n this.mapL['A'].addLayers(this.mirrorLayers);\r\n this.mapL['A'].getLayers().forEach((l) => {\r\n if (l.zindex_ !== 0) { l.setVisible(false); }\r\n });\r\n }\r\n if (this.showCursors) { this.addLayerCursor('A'); }\r\n return new Promise((success, fail) => {\r\n let templateOptions = '';\r\n templateOptions = {\r\n jsonp: true,\r\n vars: {\r\n translations: {\r\n title: getValueTranslate('title'),\r\n modViz0: getValueTranslate('modViz0'),\r\n modViz1: getValueTranslate('modViz1'),\r\n modViz2: getValueTranslate('modViz2'),\r\n modViz3: getValueTranslate('modViz3'),\r\n modViz4: getValueTranslate('modViz4'),\r\n modViz5: getValueTranslate('modViz5'),\r\n modViz6: getValueTranslate('modViz6'),\r\n modViz7: getValueTranslate('modViz7'),\r\n modViz8: getValueTranslate('modViz8'),\r\n modViz9: getValueTranslate('modViz9')\r\n }\r\n }\r\n };\r\n\r\n this.template = M.template.compileSync(template, templateOptions);\r\n\r\n // Button's click events\r\n this.template.querySelectorAll('button[id^=\"set-mirror-\"]')\r\n .forEach((button, modeViz) => {\r\n button.addEventListener('click', evt => {\r\n this.manageVisionPanelByCSSGrid(modeViz);\r\n })\r\n });\r\n\r\n // Apply default vision\r\n this.manageVisionPanelByCSSGrid(this.modeViz);\r\n success(this.template);\r\n });\r\n\r\n }\r\n\r\n /**\r\n * This function is called on the control activation\r\n *\r\n * @public\r\n * @function\r\n * @api stable\r\n */\r\n activate() {\r\n super.activate();\r\n }\r\n /**\r\n * This function is called on the control deactivation\r\n *\r\n * @public\r\n * @function\r\n * @api stable\r\n */\r\n deactivate() {\r\n super.deactivate();\r\n }\r\n\r\n /**\r\n * Initial configurations for applying CSS grid.\r\n * \r\n */\r\n createMapContainers() {\r\n const bigContainer = document.createElement('div');\r\n bigContainer.id = \"lienzo\";\r\n bigContainer.classList.add('mirrorpanel-grid');\r\n\r\n const mapjsA = document.getElementById(\"mapjs\") || document.getElementById(\"map\");\r\n document.body.insertBefore(bigContainer, mapjsA);\r\n mapjsA.classList.add('mirror1');\r\n bigContainer.appendChild(mapjsA);\r\n\r\n const mapjsB = document.createElement('div');\r\n mapjsB.id = \"mapjsB\";\r\n mapjsB.classList.add('mirror2');\r\n bigContainer.appendChild(mapjsB);\r\n\r\n const mapjsC = document.createElement('div');\r\n mapjsC.id = \"mapjsC\";\r\n mapjsC.classList.add('mirror3');\r\n bigContainer.appendChild(mapjsC);\r\n\r\n const mapjsD = document.createElement('div');\r\n mapjsD.id = \"mapjsD\";\r\n mapjsD.classList.add('mirror4');\r\n bigContainer.appendChild(mapjsD);\r\n }\r\n\r\n /**\r\n * This function shows/hides panel for differents viz options.\r\n * The mirror maps are launched from here\r\n * \r\n */\r\n manageVisionPanelByCSSGrid(modeViz) {\r\n let oldModeViz = this.modeViz;\r\n let map0 = document.getElementById('mapjs') || document.getElementById('map');\r\n map0.style.display = 'none';\r\n document.getElementById('mapjsB').style.display = 'none';\r\n document.getElementById('mapjsC').style.display = 'none';\r\n document.getElementById('mapjsD').style.display = 'none';\r\n this.template.querySelector('#set-mirror-' + oldModeViz).classList.remove('buttom-pressed');\r\n\r\n for (let i = 0; i < 10; i++) {\r\n document.getElementById('lienzo').classList.remove('modeViz' + i);\r\n }\r\n document.getElementById('lienzo').classList.add('modeViz' + modeViz);\r\n\r\n //Create map objects by modeviz\r\n if ([1, 2].includes(modeViz)) {\r\n if (this.mapL['B'] == null) {\r\n this.createMapObjects('B');//Create MapB\r\n }\r\n }\r\n if ([3, 7, 8, 9].includes(modeViz)) {\r\n if (this.mapL['B'] == null) {\r\n this.createMapObjects('B');//Create MapB\r\n }\r\n if (this.mapL['C'] == null) {\r\n this.createMapObjects('C');//Create MapC\r\n }\r\n }\r\n if ([4, 5, 6].includes(modeViz)) {\r\n if (this.mapL['B'] == null) {\r\n this.createMapObjects('B');//Create MapB\r\n }\r\n if (this.mapL['C'] == null) {\r\n this.createMapObjects('C');//Create MapC\r\n }\r\n if (this.mapL['D'] == null) {\r\n this.createMapObjects('D');//Create MapD\r\n }\r\n }\r\n\r\n this.modeViz = modeViz;\r\n this.template.querySelector('#set-mirror-' + modeViz).classList.add('buttom-pressed');\r\n this.map_.refresh();\r\n if (this.mapL['B'] !== null) { this.mapL['B'].refresh(); }\r\n if (this.mapL['C'] !== null) { this.mapL['C'].refresh(); }\r\n if (this.mapL['D'] !== null) { this.mapL['D'].refresh(); }\r\n }\r\n\r\n /**\r\n * Create mirror map object synchro with the main map\r\n */\r\n createMapObjects(mapLyr) {\r\n let defLyr = null;\r\n switch (mapLyr) {\r\n case 'B':\r\n if (this.defaultBaseLyrs[1]) defLyr = this.defaultBaseLyrs[0];\r\n break;\r\n case 'C':\r\n if (this.defaultBaseLyrs[2]) defLyr = this.defaultBaseLyrs[1];\r\n break;\r\n case 'D':\r\n if (this.defaultBaseLyrs[3]) defLyr = this.defaultBaseLyrs[2];\r\n break;\r\n default:\r\n defLyr = this.map_.getLayers()[0].setMap(this);\r\n break;\r\n }\r\n this.mapL[mapLyr] = M.map({\r\n container: 'mapjs' + mapLyr,\r\n layers: defLyr,\r\n controls: this.showTOC ? ['layerswitcher'] : '',\r\n center: this.map_.getCenter(),\r\n projection: this.map_.getProjection().code + '*' + this.map_.getProjection().units,\r\n zoom: this.map_.getZoom(),\r\n });\r\n this.mapL[mapLyr].getMapImpl().setView(this.map_.getMapImpl().getView());\r\n\r\n if (this.showCursors) { this.addLayerCursor(mapLyr); }\r\n if (this.mirrorLayers.length > 0) {\r\n this.mapL[mapLyr].addLayers(this.mirrorLayers);\r\n this.mapL[mapLyr].getLayers().forEach((l) => {\r\n if (l.zindex_ !== 0) { l.setVisible(false); }\r\n });\r\n }\r\n this.mapL[mapLyr].refresh();\r\n }\r\n\r\n /**\r\n * Adding a layer for cursor on Map\r\n */\r\n addLayerCursor(mapLyr) {\r\n // Cursor Layer\r\n this.lyrCursor[mapLyr] = new M.layer.Vector({\r\n name: 'Coordenadas centro ' + mapLyr,\r\n }, { displayInLayerSwitcher: false });\r\n\r\n this.featureLyrCursor[mapLyr] = new M.Feature('Center' + mapLyr, {\r\n type: 'Feature',\r\n properties: {},\r\n geometry: {\r\n type: 'Point',\r\n coordinates: this.mapL[mapLyr].getCenter(),\r\n },\r\n });\r\n\r\n this.lyrCursor[mapLyr].addFeatures([this.featureLyrCursor[mapLyr]]);\r\n this.lyrCursor[mapLyr].setStyle(this.styleCursor);\r\n this.lyrCursor[mapLyr].setZIndex(5000);\r\n this.mapL[mapLyr].addLayers(this.lyrCursor[mapLyr]);\r\n\r\n this.mapL[mapLyr].getMapImpl().on('pointermove', (event) => {\r\n this.lyrCursor[mapLyr].setVisible(false);\r\n Object.keys(this.featureLyrCursor).forEach(k => {\r\n if (this.mapL[k]) {\r\n this.mapL[k].getMapImpl().setView(this.mapL[mapLyr].getMapImpl().getView());\r\n }\r\n if (k != mapLyr) {\r\n if (this.featureLyrCursor[k] !== null) {\r\n this.lyrCursor[k].setVisible(true);\r\n this.featureLyrCursor[k].setGeometry({\r\n type: 'Point',\r\n coordinates: event.coordinate,\r\n });\r\n }\r\n }\r\n })\r\n });\r\n\r\n }\r\n\r\n /**\r\n * This function is called to remove the effects\r\n *\r\n * @public\r\n * @function\r\n * @api stable\r\n */\r\n removeMaps() {\r\n this.mapL['B'] = null;\r\n this.mapL['C'] = null;\r\n this.mapL['D'] = null;\r\n }\r\n\r\n destroyMapsContainer() {\r\n // Remove mirrors containers\r\n document.getElementById(\"mapjsB\").remove();\r\n document.getElementById(\"mapjsC\").remove();\r\n document.getElementById(\"mapjsD\").remove();\r\n\r\n // Take the main map out of the container\r\n const lienzo = document.getElementById(\"lienzo\");\r\n const mapjsA = document.getElementById(\"mapjs\") || document.getElementById(\"map\");\r\n mapjsA.style.display = \"block\";\r\n mapjsA.classList.remove('mirror1');\r\n document.body.insertBefore(mapjsA, lienzo);\r\n\r\n // Load the main container\r\n document.getElementById(\"lienzo\").remove();\r\n }\r\n\r\n /**\r\n * This function compares controls\r\n *\r\n * @public\r\n * @function\r\n * @param {M.Control} control to compare\r\n * @api stable\r\n */\r\n equals(control) {\r\n return control instanceof MirrorpanelControl;\r\n }\r\n}\r\n","/**\r\n * @module M/plugin/Mirrorpanel\r\n */\r\nimport 'assets/css/mirrorpanel';\r\nimport MirrorpanelControl from './mirrorpanelcontrol';\r\nimport api from '../../api';\r\nimport { getValue } from './i18n/language'; //e2m: Multilanguage support\r\n\r\nexport default class Mirrorpanel extends M.Plugin {\r\n /**\r\n * @classdesc\r\n * Main facade plugin object. This class creates a plugin\r\n * object which has an implementation Object\r\n *\r\n * @constructor\r\n * @extends {M.Plugin}\r\n * @param {Object} impl implementation object\r\n * @api stable\r\n */\r\n constructor(options = {}) {\r\n super();\r\n\r\n /**\r\n * Name plugin\r\n * @private\r\n * @type {String}\r\n */\r\n this.name_ = 'mirrorpanel';\r\n\r\n /**\r\n * Facade of the map\r\n * @private\r\n * @type {M.Map}\r\n */\r\n this.map_ = null;\r\n\r\n /**\r\n * Array of controls\r\n * @private\r\n * @type {Array}\r\n */\r\n this.controls_ = [];\r\n\r\n /**\r\n * Class name of the html view Plugin\r\n * @public\r\n * @type {string}\r\n */\r\n this.className = 'm-plugin-mirrorpanel';\r\n\r\n /**\r\n * Position of the Plugin\r\n * @public\r\n * Posible values: TR | TL | BL | BR\r\n * @type {String}\r\n */\r\n const positions = ['TR', 'TL', 'BL', 'BR'];\r\n this.position = positions.includes(options.position) ? options.position : 'TR';\r\n\r\n /**\r\n * Collapsed attribute\r\n * @public\r\n * @type {boolean}\r\n */\r\n this.collapsed = options.collapsed;\r\n if (this.collapsed === undefined) this.collapsed = true;\r\n\r\n /**\r\n * Collapsible attribute\r\n * @public\r\n * @type {boolean}\r\n */\r\n this.collapsible = options.collapsible;\r\n if (this.collapsible === undefined) this.collapsible = true;\r\n\r\n /**\r\n * Modo de visualización\r\n * Value: number in range 0 - 9\r\n * @type {number}\r\n * @public\r\n */\r\n this.modeViz = options.modeViz;\r\n if (this.modeViz === undefined) this.modeViz = 0;\r\n\r\n /**\r\n * Enabled key functions\r\n * @type {boolean}\r\n * @public\r\n */\r\n this.enabledKeyFunctions = options.enabledKeyFunctions;\r\n if (this.enabledKeyFunctions === undefined) this.enabledKeyFunctions = true;\r\n\r\n /**\r\n * Enabled synchro cursors\r\n * @type {boolean}\r\n * @public\r\n */\r\n this.showCursors = options.showCursors;\r\n if (this.showCursors === undefined) this.showCursors = true;\r\n\r\n /**\r\n * Layer names that will have effects\r\n * @public\r\n * Value: the names separated with coma\r\n * @type {string}\r\n */\r\n\r\n this.mirrorLayers = [];\r\n if (options.mirrorLayers !== undefined) {\r\n if (Array.isArray(options.mirrorLayers)) {\r\n this.mirrorLayers = options.mirrorLayers;\r\n } else {\r\n this.mirrorLayers = options.mirrorLayers.split(\",\");\r\n }\r\n }\r\n\r\n /**\r\n * Layer base for the three mirror maps\r\n * @public\r\n * Value: the names separated with coma\r\n * @type {string}\r\n */\r\n\r\n this.defaultBaseLyrs = [];\r\n if (options.defaultBaseLyrs !== undefined) {\r\n if (Array.isArray(options.defaultBaseLyrs)) {\r\n this.defaultBaseLyrs = options.defaultBaseLyrs;\r\n } else {\r\n this.defaultBaseLyrs = options.defaultBaseLyrs.split(\",\");\r\n }\r\n }\r\n\r\n /** \r\n * Show interface\r\n *@public\r\n *@type{boolean}\r\n */\r\n this.interface = options.interface === undefined ? true : options.interface;\r\n\r\n /**\r\n * Enabled layerswitcher control on mirrors \r\n * @type {boolean}\r\n * @public\r\n */\r\n this.showTOC = options.showTOC;\r\n if (this.showTOC === undefined) this.showTOC = true;\r\n\r\n\r\n /**\r\n *@private\r\n *@type { string }\r\n */\r\n this.tooltip_ = options.tooltip || getValue('tooltip');\r\n\r\n\r\n /**\r\n * Metadata from api.json\r\n * @private\r\n * @type {Object}\r\n */\r\n this.metadata_ = api.metadata;\r\n }\r\n\r\n /**\r\n * This function adds this plugin into the map\r\n *\r\n * @public\r\n * @function\r\n * @param {M.Map} map the map to add the plugin\r\n * @api stable\r\n */\r\n addTo(map) {\r\n const pluginOnLeft = !!(['TL', 'BL'].includes(this.position));\r\n\r\n const values = {\r\n pluginOnLeft,\r\n collapsible: this.collapsible,\r\n collapsed: this.collapsed,\r\n modeViz: this.modeViz,\r\n showCursors: this.showCursors,\r\n mirrorLayers: this.mirrorLayers,\r\n defaultBaseLyrs: this.defaultBaseLyrs,\r\n showTOC: this.showTOC\r\n };\r\n\r\n this.control_ = new MirrorpanelControl(values);\r\n this.controls_.push(this.control_);\r\n this.map_ = map;\r\n\r\n this.panel_ = new M.ui.Panel('panelMirrorpanel', {\r\n collapsible: this.collapsible,\r\n collapsed: this.collapsed,\r\n position: M.ui.position[this.position],\r\n modeViz: this.modeViz,\r\n showCursors: this.showCursors,\r\n className: this.interface ? 'm-plugin-panelMirrorpanel' : 'm-plugin-panelMirrorpanel hidden',\r\n collapsedButtonClass: 'mirrorpanel-icon',\r\n tooltip: this.tooltip_,\r\n });\r\n this.panel_.addControls(this.controls_);\r\n map.addPanels(this.panel_);\r\n\r\n // Keybindings for Ctrl + Shift + (F1-F8) / ESC\r\n document.addEventListener('keydown', (zEvent) => {\r\n if (!this.enabledKeyFunctions) {\r\n return;\r\n }\r\n for (let i = 0; i < 10; i++) {\r\n if (zEvent.ctrlKey && zEvent.shiftKey && zEvent.key === \"F\" + (i + 1)) { // case sensitive\r\n this.control_.manageVisionPanelByCSSGrid(i);\r\n }\r\n }\r\n var keyStr = [\"Control\", \"Shift\", \"Alt\", \"Meta\"].includes(zEvent.key) ? \"\" : zEvent.key;\r\n\r\n var combinedKeys = (zEvent.ctrlKey ? \"Control \" : \"\") +\r\n (zEvent.shiftKey ? \"Shift \" : \"\") +\r\n (zEvent.altKey ? \"Alt \" : \"\") +\r\n (zEvent.metaKey ? \"Meta \" : \"\") + keyStr;\r\n if (combinedKeys === \"Escape\") {\r\n this.control_.manageVisionPanelByCSSGrid(0);\r\n }\r\n\r\n });\r\n\r\n }\r\n\r\n /**\r\n * This function destroys this plugin\r\n *\r\n * @public\r\n * @function\r\n * @api stable\r\n */\r\n destroy() {\r\n document.removeEventListener('keydown', (zEvent) => { });\r\n this.control_.removeMaps();\r\n this.control_.destroyMapsContainer();\r\n this.map_.removeControls([this.control_]);\r\n [this.control_, this.panel_, this.map_, this.collapsible, this.collapsed, this.modeViz, this.enabledKeyFunctions, this.showCursors, this.mirrorLayers, this.defaultBaseLyrs, this.interface, this.showTOC] = [null, null, null, null, null, null, null, null, null, null, null, null];\r\n }\r\n\r\n /**\r\n * This function gets name plugin\r\n * @getter\r\n * @public\r\n * @returns {string}\r\n * @api stable\r\n */\r\n get name() {\r\n return this.name_;\r\n }\r\n\r\n /**\r\n * This function gets metadata plugin\r\n *\r\n * @public\r\n * @function\r\n * @api stable\r\n */\r\n getMetadata() {\r\n return this.metadata_;\r\n }\r\n\r\n /**\r\n * Get the API REST Parameters of the plugin\r\n *\r\n * @function\r\n * @public\r\n * @api\r\n */\r\n getAPIRest() {\r\n return `${this.name}=${this.position}*!${this.collapsed}*!${this.collapsible}*!${this.modeViz}*!${this.enabledKeyFunctions}*!${this.showCursors}*!${this.mirrorLayers}*!${this.defaultBaseLyrs}*!${this.interface}*!${this.showTOC}`;\r\n }\r\n\r\n /**\r\n * Activate plugin\r\n *\r\n * @function\r\n * @public\r\n * @api\r\n */\r\n activate() {\r\n this.control_.activate();\r\n }\r\n\r\n /**\r\n * Desactivate plugin\r\n *\r\n * @function\r\n * @public\r\n * @api\r\n */\r\n deactivate() {\r\n this.control_.deactivate();\r\n }\r\n\r\n\r\n}\r\n","import M$plugin$Mirrorpanel from '/home/irenevinas/m5/mapea-publico/src/plugins/v5/mirrorpanel/src/facade/js/mirrorpanel';\nimport M$control$MirrorpanelControl from '/home/irenevinas/m5/mapea-publico/src/plugins/v5/mirrorpanel/src/facade/js/mirrorpanelcontrol';\nimport M$impl$control$MirrorpanelControl from '/home/irenevinas/m5/mapea-publico/src/plugins/v5/mirrorpanel/src/impl/ol/js/mirrorpanelcontrol';\n\nif (!window.M.plugin) window.M.plugin = {};\nif (!window.M.control) window.M.control = {};\nif (!window.M.impl) window.M.impl = {};\nif (!window.M.impl.control) window.M.impl.control = {};\nwindow.M.plugin.Mirrorpanel = M$plugin$Mirrorpanel;\nwindow.M.control.MirrorpanelControl = M$control$MirrorpanelControl;\nwindow.M.impl.control.MirrorpanelControl = M$impl$control$MirrorpanelControl;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..326344c --- /dev/null +++ b/docs/README.md @@ -0,0 +1,116 @@ +# M.plugin.Mirrorpanel + +Plugin que permite comparar varias capas dividiendo la pantalla en varias partes. Los mapas tienen sus vistas sincronizadas, y podemos ver la representación de una misma zona por distintas capas. + +![Imagen - Cortina Vertical](../img/mirrorpanel_1.png) + + +# Dependencias + +- mirrorpanel.ol.min.js +- mirrorpanel.ol.min.css + + +```html + + +``` + +# Parámetros + +- El constructor se inicializa con un JSON de options con los siguientes atributos: + +- **position**. Indica la posición donde se mostrará el plugin. + - 'TL':top left + - 'TR':top right (default) + - 'BL':bottom left + - 'BR':bottom right + +- **collapsible**. Si es *true*, el botón aparece, y puede desplegarse y contraerse. Si es *false*, el botón no aparece. Por defecto tiene el valor *true*. + +- **collapsed**. Si es *true*, el panel aparece cerrado. Si es *false*, el panel aparece abierto. Por defecto tiene el valor *true*. + +- **modeViz**. Define el tipo de comparación con la que arranca. Rango 0-9. + - 0: mapa simple. + - 1: dos mapas en vertical. + - 2: dos mapas en horizontal. + - 3: tres mapas en vertical. + - 4: cuatro mapas en vertical. + - 5: mosaico con cuatro mapas. + - 6: cuatro mapas en horizontal. + - 7: tres mapas en proporción 2-1-1. + - 8: un mapa arriba y dos abajo. + - 9: dos mapas arriba y uno abajo. + +- **enabledKeyFunctions**. Si es *true*, se pueden usar las combinaciones de teclas Ctrl + Shift + [F1-F8] para cambiar entre los distintos modos de visualización. Con la tecla *Escape* se destruye el plugin. Por defecto tiene el valor *true*. + +- **showCursors**. Si es *true*, muestra cursores sincronziados en cda unao de los mapas espejo. Por defecto tiene el valor *true*. + +- **mirrorLayers**. Es un array de capas para mostrar en los mapas espejo y poder compararlas entre sí. + +- **defaultBaseLyrs**. Es un array de capas para mostrar como mapa por defecto. + +- **interface**. Define si mostrar o no la interfaz del plugin. + +- **showTOC**. si es *true* mostrará el control layerswitcher en las capas espejo. + +# Eventos + +# Multi idioma + +Actualmente viene preparado para español e inglés. Para definir con qué idioma arranca, hay que ir al fichero test.js y modificar + +```javascript +M.language.setLang('es');//Idioma español +M.language.setLang('en');//Idioma inglés +``` +Se pueden crear más ficheros de idioma. Basta con copiar la estructura de los ficheros **json** de la carpeta *\src\facade\js\i18n* , renombrar con la abreviatura del nuevo idioma (fr para el fránces), y cambiar los textos, manteniendo las *keywords*. + +# Ejemplos de uso + +## Ejemplo base + +```javascript +const map = M.map({ + container: 'mapjs', + center: { + x: -667143.31, + y: 4493011.77, + }, + projection: "EPSG:3857*m", + zoom: 8, +}); + +const mpMirrorPanel = new M.plugin.Mirrorpanel(); +map.addPlugin(mpMirrorPanel); +``` + +## Ejemplo 1 + +```javascript +const map = M.map({ + container: 'mapjs', + center: { + x: -667143.31, + y: 4493011.77, + }, + projection: "EPSG:3857*m", + zoom: 8, +}); + +const mpMirrorPanel = new M.plugin.Mirrorpanel({ + position: 'TR', + collapsible: true, + collapsed: false, + modeViz: 0, + enabledKeyFunctions: true, + showCursors: true, + defaultBaseLyrs: [ + 'WMTS*http://www.ign.es/wmts/mapa-raster?*MTN*GoogleMapsCompatible*MTN', + 'WMTS*http://www.ign.es/wmts/pnoa-ma?*OI.OrthoimageCoverage*GoogleMapsCompatible*PNOA', + 'WMTS*https://wmts-mapa-lidar.idee.es/lidar?*EL.GridCoverageDSM*GoogleMapsCompatible*LiDAR', + ], +}); + +map.addPlugin(mpMirrorPanel); +``` \ No newline at end of file diff --git a/img/mirrorpanel_1.png b/img/mirrorpanel_1.png new file mode 100644 index 0000000..65eb85d Binary files /dev/null and b/img/mirrorpanel_1.png differ diff --git a/package.json b/package.json new file mode 100644 index 0000000..c0c4932 --- /dev/null +++ b/package.json @@ -0,0 +1,58 @@ +{ + "name": "Mirrorpanel", + "version": "1.0.0", + "description": "", + "keywords": [ + "map", + "mapping", + "tool", + "sigcorporativo-ja", + "mapea", + "plugin" + ], + "license": "ISC", + "scripts": { + "start": "webpack-dev-server --config=webpack-config/webpack.development.config.js", + "prebuild": "node task/create-entrypoint.js", + "build": "webpack --config=webpack-config/webpack.production.config.js", + "test-build": "npm run build && live-server --open=test/prod.html", + "check": "eslint ./src", + "fix": "eslint --fix ./src" + }, + "author": "", + "devDependencies": { + "@babel/core": "^7.10.3", + "@babel/plugin-proposal-export-default-from": "^7.0.0-beta.51", + "@babel/preset-env": "^7.10.3", + "async": "2.1.4", + "babel-eslint": "^10.0.1", + "babel-loader": "^8.0.0-beta.4", + "copy-webpack-plugin": "^4.5.2", + "cross-env": "^5.2.0", + "css-loader": "^2.1.1", + "derequire": "2.0.6", + "eslint": "^4.19.1", + "eslint-loader": "^2.0.0", + "eslint-plugin-import": "^2.21.2", + "eslint-plugin-jsx-a11y": "^6.3.1", + "eslint-plugin-react": "^7.7.0", + "file-loader": "^1.1.11", + "fs-extra": "2.0.0", + "handlebars": "^4.0.11", + "html-loader": "^0.5.5", + "live-server": "^1.2.1", + "mini-css-extract-plugin": "^0.4.1", + "minimist": "^1.2.0", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "slash": "^3.0.0", + "style-loader": "^0.21.0", + "supports-color": "^5.3.0", + "terser-webpack-plugin": "^1.4.4", + "uglify-js": "^2.6.1", + "uglifycss": "0.0.29", + "url-loader": "^1.0.1", + "webpack": "^4.12.0", + "webpack-cli": "^3.3.12", + "webpack-dev-server": "^3.1.14" + } +} diff --git a/src/api.json b/src/api.json new file mode 100644 index 0000000..53c0a1a --- /dev/null +++ b/src/api.json @@ -0,0 +1,120 @@ +{ + "url": { + "name": "mirrorpanel", + "separator": "*!" + }, + "constructor": "M.plugin.Mirrorpanel", + "parameters": [ + { + "type": "object", + "properties": [ + { + "type": "simple", + "name": "position", + "possibleValues": [ + "TL", + "TR", + "BL", + "BR" + ], + "position": 0 + }, + { + "type": "boolean", + "name": "collapsed", + "position": 1 + }, + { + "type": "boolean", + "name": "collapsible", + "position": 2 + }, + { + "type": "simple", + "name": "modeViz", + "position": 3 + }, + { + "type": "boolean", + "name": "enabledKeyFunctions", + "position": 4 + }, + { + "type": "boolean", + "name": "showCursors", + "position": 5 + }, + { + "type": "simple", + "name": "mirrorLayers", + "position": 6 + }, + { + "type": "simple", + "name": "defaultBaseLyrs", + "position": 7 + }, + { + "type": "boolean", + "name": "interface", + "position": 8 + }, + { + "type": "boolean", + "name": "showToc", + "position": 9 + } + ] + } + ], + "files": { + "ol": { + "scripts": ["mirrorpanel.ol.min.js"], + "styles": ["mirrorpanel.ol.min.css"] + } + }, + "metadata": { + "uuid_plugin": "", + "uuid_version_plugin": "", + "version_ficha_metadatos": "", + "name": "Mirrorpanel", + "description": "Plugin que permite comparar varias capas dividiendo la pantalla en varias partes.", + "text": "Plugin que permite comparar varias capas dividiendo la pantalla en varias partes. Los mapas tienen sus vistas sincronizadas, y podemos ver la representación de una misma zona por distintas capas.", + "version": "1.0.0", + "date": "Julio, 2020", + "author": "", + "org": "", + "tags": "mapea,plugin", + "icon": "./facade/assets/icons/icons.svg", + "buttons": [ + { + "title": "", + "description": "", + "querySelector": "" + }, + { + "title": "", + "description": "", + "querySelector": "" + } + ], + "dependencies": { + "modules": [ + "", + "" + ], + "plugins": [ + { + "uuid": "", + "name": "" + } + ], + "services": [ + { + "name": "", + "description": "" + } + ] + } + } +} \ No newline at end of file diff --git a/src/facade/assets/css/mirrorpanel.css b/src/facade/assets/css/mirrorpanel.css new file mode 100644 index 0000000..64b14e3 --- /dev/null +++ b/src/facade/assets/css/mirrorpanel.css @@ -0,0 +1,338 @@ + + +/** Estilos sobreescritos */ + +@font-face { + font-family: 'mirrorpanel'; + src: url('../fonts/mirrorpanel.eot?b6yytp'); + src: url('../fonts/mirrorpanel.eot?b6yytp#iefix') format('embedded-opentype'), url('../fonts/mirrorpanel.ttf?b6yytp') format('truetype'), url('../fonts/mirrorpanel.woff?b6yytp') format('woff'), url('../fonts/mirrorpanel.svg?b6yytp#mirrorpanel') format('svg'); + font-weight: normal; + font-style: normal; + font-display: block; +} + + +/** Estilos propios*/ + +.info { + position: absolute; + width: 60%; + padding: 5px; + top: 10px; + left: 20%; + background: rgba(245, 245, 245, 0.8); + font-size: large; + border-radius: 5px; + border-style: dashed; + border-width: 2px; + text-align: center; +} + +.m-panel-btn.mirrorpanel-icon { + /*color: #e8f5e9 !important;*/ + color: #718bd3 !important; +} + +.m-plugin-panelMirrorpanel.hidden { + display: none; +} + +div.m-plugin-panelMirrorpanel.opened>.m-panel-btn.g-cartografia-flecha-derecha, +div.m-plugin-panelMirrorpanel.opened>.m-panel-btn.g-cartografia-flecha-izquierda { + color: #e8f5e9 !important; + /*color: #718bd3 !important;*/ +} + +.m-plugin-panelMirrorpanel.collapsed>div.m-panel-controls { + display: none !important; +} + +div.m-plugin-panelMirrorpanel.opened{ + min-width: max-content; +} + +/*Rolled button in panels on the right*/ + +.m-areas>div.m-area.m-right>div.m-plugin-panelMirrorpanel.opened>button.m-panel-btn { + position: absolute; + left: -2.5rem; + background-color: #718bd3; + /*background-color: #fff;*/ +} + + +/*Rolled button in panels on the left*/ + +.m-areas>div.m-area.m-left>div.m-plugin-panelMirrorpanel.opened>button.m-panel-btn { + position: absolute; + right: -2.5rem; + left: unset !important; + background-color: #718bd3; + /*background-color: #fff;*/ +} + +.div-m-mirrorpanel-panel { + padding: .7rem; +} + +.m-mirrorpanel-effect-buttoms { + padding: 0.3rem 0; + text-align: center; +} + +div#m-mirrorpanel-titulo { + /*background-color: #718bd3; + color: white;*/ + display: block; + font-size: 15px; + height: 40px; + line-height: 40px; + padding: 0 0.3rem; + text-align: center; + border-radius: 4px 4px 0 0; + border-bottom: 1.5px solid rgba(0, 0, 0, .12); +} + + +/* +Estilos del botón +*/ + +.m-mirrorpanel-container .big-button { + font-size: 32px; + background: none; + border: none; + cursor: pointer; + opacity: .75; + transition: all .25s ease; + color: #404040; + outline: none; +} + +.m-mirrorpanel-container .big-button:hover { + color: #718bd3; +} + +.m-mirrorpanel-container .buttom-pressed { + color: #718bd3; +} + +[class^="mirrorpanel-"], +[class*=" mirrorpanel-"] { + font-family: 'mirrorpanel' !important; + speak: never; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +[class^="mirrorpanel-"]:before, +[class*=" mirrorpanel-"]:before { + display: block; +} + +.mirrorpanel-icon:before { + content: "\e802"; + font-family: 'mirrorpanel' !important; +} + +.mirrorpanel-modeviz0:before { + content: "\e804"; +} + +.mirrorpanel-modeviz1:before { + content: "\e803"; +} + +.mirrorpanel-modeviz2:before { + content: "\e803"; + transform: rotate(90deg); +} + +.mirrorpanel-modeviz3:before { + content: "\e805"; +} + +.mirrorpanel-modeviz4:before { + content: "\e806"; +} + +.mirrorpanel-modeviz5:before { + content: "\e808"; +} + +.mirrorpanel-modeviz6:before { + content: "\e806"; + transform: rotate(90deg); +} + +.mirrorpanel-modeviz7:before { + content: "\e807"; +} + +.mirrorpanel-modeviz8:before { + content: "\e809"; +} + +.mirrorpanel-modeviz9:before { + content: "\e809"; + transform: rotate(180deg); +} + + +/* Grid classes */ + +.mirrorpanel-grid { + display: grid; + height: 100%; + width: 100%; + margin: 0; + padding: 0; + grid-template-columns: 1fr; + grid-template-rows: 1fr; + gap: 1px 1px; + grid-template-areas: mirror1; +} + +.mirrorpanel-grid .mirror1, +.mirrorpanel-grid .mirror2, +.mirrorpanel-grid .mirror3, +.mirrorpanel-grid .mirror4 { + display: none; + min-height: 100%; +} + +.mirrorpanel-grid .mirror1, +.mirrorpanel-grid:not(.modeViz0) .mirror2, +.mirrorpanel-grid:not(.modeViz0):not(.modeViz1):not(.modeViz2) .mirror3, +.mirrorpanel-grid.modeViz4 .mirror4, +.mirrorpanel-grid.modeViz5 .mirror4, +.mirrorpanel-grid.modeViz6 .mirror4 { + display: block !important; +} + +.mirror1 { grid-area: mirror1; } +.mirror2 { grid-area: mirror2; } +.mirror3 { grid-area: mirror3; } +.mirror4 { grid-area: mirror4; } + +/** + * | A | + */ + +.mirrorpanel-grid.modeViz0 { + grid-template-columns: 1fr !important; + grid-template-rows: 1fr !important; + grid-template-areas: 'mirror1' !important; +} + + +/** + * | A | B | + */ + +.mirrorpanel-grid.modeViz1 { + grid-template-columns: 1fr 1fr !important; + grid-template-rows: 1fr !important; + grid-template-areas: 'mirror1 mirror2' !important; +} + + +/** +* | A | +* | B | +*/ + +.mirrorpanel-grid.modeViz2 { + grid-template-columns: 1fr !important; + grid-template-rows: 1fr 1fr !important; + grid-template-areas: 'mirror1' 'mirror2' !important; +} + + +/** +* | A | B | C | +*/ + +.mirrorpanel-grid.modeViz3 { + grid-template-columns: 1fr 1fr 1fr !important; + grid-template-rows: 1fr !important; + grid-template-areas: 'mirror1 mirror2 mirror3' !important; +} + + +/** +* | A | B | C | D | +*/ + +.mirrorpanel-grid.modeViz4 { + grid-template-columns: 1fr 1fr 1fr 1fr !important; + grid-template-rows: 1fr !important; + grid-template-areas: 'mirror1 mirror2 mirror3 mirror4' !important; +} + + +/** +* | A | B | +* | C | D | +*/ + +.mirrorpanel-grid.modeViz5 { + grid-template-columns: 1fr 1fr !important; + grid-template-rows: 1fr 1fr !important; + grid-template-areas: 'mirror1 mirror2' 'mirror3 mirror4' !important; +} + + +/** +* | A | +* | B | +* | C | +* | D | +*/ + +.mirrorpanel-grid.modeViz6 { + grid-template-columns: 1fr !important; + grid-auto-rows: 1fr 1fr 1fr 1fr !important; + grid-template-areas: 'mirror1' 'mirror2' 'mirror3' 'mirror4' !important; +} + + +/** +* | A | B | C | +*/ + +.mirrorpanel-grid.modeViz7 { + grid-template-columns: 2fr 1fr 1fr !important; + grid-template-rows: 1fr !important; + grid-template-areas: 'mirror1 mirror2 mirror3' !important; +} + + +/** +* | A | +* | B | C | +*/ + +.mirrorpanel-grid.modeViz8 { + grid-template-columns: 1fr 1fr !important; + grid-template-rows: 1fr 1fr !important; + grid-template-areas: 'mirror1 mirror1' 'mirror2 mirror3' !important; +} + + +/** +* | A | B | +* | C | +*/ + +.mirrorpanel-grid.modeViz9 { + grid-template-columns: 1fr 1fr !important; + grid-template-rows: 1fr 1fr !important; + grid-template-areas: 'mirror1 mirror2' 'mirror3 mirror3' !important; +} + diff --git a/src/facade/assets/fonts/mirrorpanel.eot b/src/facade/assets/fonts/mirrorpanel.eot new file mode 100644 index 0000000..f73cd5b Binary files /dev/null and b/src/facade/assets/fonts/mirrorpanel.eot differ diff --git a/src/facade/assets/fonts/mirrorpanel.svg b/src/facade/assets/fonts/mirrorpanel.svg new file mode 100644 index 0000000..1bd488a --- /dev/null +++ b/src/facade/assets/fonts/mirrorpanel.svg @@ -0,0 +1,18 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/facade/assets/fonts/mirrorpanel.ttf b/src/facade/assets/fonts/mirrorpanel.ttf new file mode 100644 index 0000000..2db837c Binary files /dev/null and b/src/facade/assets/fonts/mirrorpanel.ttf differ diff --git a/src/facade/assets/fonts/mirrorpanel.woff b/src/facade/assets/fonts/mirrorpanel.woff new file mode 100644 index 0000000..9590c1a Binary files /dev/null and b/src/facade/assets/fonts/mirrorpanel.woff differ diff --git a/src/facade/assets/icons/icon.svg b/src/facade/assets/icons/icon.svg new file mode 100644 index 0000000..d67d177 --- /dev/null +++ b/src/facade/assets/icons/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/facade/js/i18n/en.json b/src/facade/js/i18n/en.json new file mode 100644 index 0000000..90c2fb8 --- /dev/null +++ b/src/facade/js/i18n/en.json @@ -0,0 +1,14 @@ +{ + "tooltip": "Mirror Comparison", + "title": "Mirror Maps", + "modViz0": "Standard map", + "modViz1": "Vertical two maps", + "modViz2": "Horizontal two maps", + "modViz3": "Vertical three maps", + "modViz4": "Vertical four maps", + "modViz5": "Mosaic maps", + "modViz6": "Horizontal four maps", + "modViz7": "Vertical 2-1-1 proportional maps", + "modViz8": "One map above and two below", + "modViz9": "Two maps above and one below" +} diff --git a/src/facade/js/i18n/es.json b/src/facade/js/i18n/es.json new file mode 100644 index 0000000..e3b12d6 --- /dev/null +++ b/src/facade/js/i18n/es.json @@ -0,0 +1,14 @@ +{ + "tooltip": "Comparador de mapas espejo", + "title": "Mapas espejo", + "modViz0": "Mapa standard", + "modViz1": "Dos mapas en vertical", + "modViz2": "Dos mapas en horizontal", + "modViz3": "Tres mapas en vertical", + "modViz4": "Cuatro mapas en vertical", + "modViz5": "Mosaico de mapas", + "modViz6": "Cuatro mapas en horizontal", + "modViz7": "Tres mapas en proporción 2-1-1", + "modViz8": "Un mapa arriba y dos abajo", + "modViz9": "Dos mapas arriba y uno abajo" +} diff --git a/src/facade/js/i18n/language.js b/src/facade/js/i18n/language.js new file mode 100644 index 0000000..682ea35 --- /dev/null +++ b/src/facade/js/i18n/language.js @@ -0,0 +1,69 @@ +import en from './en'; +import es from './es'; + +/** + * Default object with es and en translate. + * + * @const + * @type {object} + */ +const translations = { + en, + es, +}; + +const getLang = () => { + let res = 'es'; + if (typeof M.language.getLang === 'function') { + res = M.language.getLang(); + } + + return res; +}; + +/** + * This function sets a new language translate. + * @param {string} lang + * @param {JSON} json + * @public + * @api + */ +export const addTranslation = (lang, json) => { + translations[lang] = json; +}; + +/** + * This function gets a language translate. + * + * @param {string} lang + * @return {JSON} + * @public + * @api + */ +export const getTranslation = (lang) => { + return translations[lang]; +}; + +/** + * This function gets a language value from key + * + * @public + * @param {string} + * @param {string} + * @return {string} + * @public + * @api + */ + +export const getValue = (keyPath, lang = getLang()) => { + const translation = getTranslation(lang); + let value = ''; + if (M.utils.isNullOrEmpty(translation)) { + /* eslint-disable no-console */ + console.warn(`The translation '${lang}' has not been defined.`); + } else { + value = keyPath.split('.').reduce((prev, current) => prev[current], translation); + } + + return value; +}; diff --git a/src/facade/js/mirrorpanel.js b/src/facade/js/mirrorpanel.js new file mode 100644 index 0000000..97199ba --- /dev/null +++ b/src/facade/js/mirrorpanel.js @@ -0,0 +1,298 @@ +/** + * @module M/plugin/Mirrorpanel + */ +import 'assets/css/mirrorpanel'; +import MirrorpanelControl from './mirrorpanelcontrol'; +import api from '../../api'; +import { getValue } from './i18n/language'; //e2m: Multilanguage support + +export default class Mirrorpanel extends M.Plugin { + /** + * @classdesc + * Main facade plugin object. This class creates a plugin + * object which has an implementation Object + * + * @constructor + * @extends {M.Plugin} + * @param {Object} impl implementation object + * @api stable + */ + constructor(options = {}) { + super(); + + /** + * Name plugin + * @private + * @type {String} + */ + this.name_ = 'mirrorpanel'; + + /** + * Facade of the map + * @private + * @type {M.Map} + */ + this.map_ = null; + + /** + * Array of controls + * @private + * @type {Array} + */ + this.controls_ = []; + + /** + * Class name of the html view Plugin + * @public + * @type {string} + */ + this.className = 'm-plugin-mirrorpanel'; + + /** + * Position of the Plugin + * @public + * Posible values: TR | TL | BL | BR + * @type {String} + */ + const positions = ['TR', 'TL', 'BL', 'BR']; + this.position = positions.includes(options.position) ? options.position : 'TR'; + + /** + * Collapsed attribute + * @public + * @type {boolean} + */ + this.collapsed = options.collapsed; + if (this.collapsed === undefined) this.collapsed = true; + + /** + * Collapsible attribute + * @public + * @type {boolean} + */ + this.collapsible = options.collapsible; + if (this.collapsible === undefined) this.collapsible = true; + + /** + * Modo de visualización + * Value: number in range 0 - 9 + * @type {number} + * @public + */ + this.modeViz = options.modeViz; + if (this.modeViz === undefined) this.modeViz = 0; + + /** + * Enabled key functions + * @type {boolean} + * @public + */ + this.enabledKeyFunctions = options.enabledKeyFunctions; + if (this.enabledKeyFunctions === undefined) this.enabledKeyFunctions = true; + + /** + * Enabled synchro cursors + * @type {boolean} + * @public + */ + this.showCursors = options.showCursors; + if (this.showCursors === undefined) this.showCursors = true; + + /** + * Layer names that will have effects + * @public + * Value: the names separated with coma + * @type {string} + */ + + this.mirrorLayers = []; + if (options.mirrorLayers !== undefined) { + if (Array.isArray(options.mirrorLayers)) { + this.mirrorLayers = options.mirrorLayers; + } else { + this.mirrorLayers = options.mirrorLayers.split(","); + } + } + + /** + * Layer base for the three mirror maps + * @public + * Value: the names separated with coma + * @type {string} + */ + + this.defaultBaseLyrs = []; + if (options.defaultBaseLyrs !== undefined) { + if (Array.isArray(options.defaultBaseLyrs)) { + this.defaultBaseLyrs = options.defaultBaseLyrs; + } else { + this.defaultBaseLyrs = options.defaultBaseLyrs.split(","); + } + } + + /** + * Show interface + *@public + *@type{boolean} + */ + this.interface = options.interface === undefined ? true : options.interface; + + /** + * Enabled layerswitcher control on mirrors + * @type {boolean} + * @public + */ + this.showTOC = options.showTOC; + if (this.showTOC === undefined) this.showTOC = true; + + + /** + *@private + *@type { string } + */ + this.tooltip_ = options.tooltip || getValue('tooltip'); + + + /** + * Metadata from api.json + * @private + * @type {Object} + */ + this.metadata_ = api.metadata; + } + + /** + * This function adds this plugin into the map + * + * @public + * @function + * @param {M.Map} map the map to add the plugin + * @api stable + */ + addTo(map) { + const pluginOnLeft = !!(['TL', 'BL'].includes(this.position)); + + const values = { + pluginOnLeft, + collapsible: this.collapsible, + collapsed: this.collapsed, + modeViz: this.modeViz, + showCursors: this.showCursors, + mirrorLayers: this.mirrorLayers, + defaultBaseLyrs: this.defaultBaseLyrs, + showTOC: this.showTOC + }; + + this.control_ = new MirrorpanelControl(values); + this.controls_.push(this.control_); + this.map_ = map; + + this.panel_ = new M.ui.Panel('panelMirrorpanel', { + collapsible: this.collapsible, + collapsed: this.collapsed, + position: M.ui.position[this.position], + modeViz: this.modeViz, + showCursors: this.showCursors, + className: this.interface ? 'm-plugin-panelMirrorpanel' : 'm-plugin-panelMirrorpanel hidden', + collapsedButtonClass: 'mirrorpanel-icon', + tooltip: this.tooltip_, + }); + this.panel_.addControls(this.controls_); + map.addPanels(this.panel_); + + // Keybindings for Ctrl + Shift + (F1-F8) / ESC + document.addEventListener('keydown', (zEvent) => { + if (!this.enabledKeyFunctions) { + return; + } + for (let i = 0; i < 10; i++) { + if (zEvent.ctrlKey && zEvent.shiftKey && zEvent.key === "F" + (i + 1)) { // case sensitive + this.control_.manageVisionPanelByCSSGrid(i); + } + } + var keyStr = ["Control", "Shift", "Alt", "Meta"].includes(zEvent.key) ? "" : zEvent.key; + + var combinedKeys = (zEvent.ctrlKey ? "Control " : "") + + (zEvent.shiftKey ? "Shift " : "") + + (zEvent.altKey ? "Alt " : "") + + (zEvent.metaKey ? "Meta " : "") + keyStr; + if (combinedKeys === "Escape") { + this.control_.manageVisionPanelByCSSGrid(0); + } + + }); + + } + + /** + * This function destroys this plugin + * + * @public + * @function + * @api stable + */ + destroy() { + document.removeEventListener('keydown', (zEvent) => { }); + this.control_.removeMaps(); + this.control_.destroyMapsContainer(); + this.map_.removeControls([this.control_]); + [this.control_, this.panel_, this.map_, this.collapsible, this.collapsed, this.modeViz, this.enabledKeyFunctions, this.showCursors, this.mirrorLayers, this.defaultBaseLyrs, this.interface, this.showTOC] = [null, null, null, null, null, null, null, null, null, null, null, null]; + } + + /** + * This function gets name plugin + * @getter + * @public + * @returns {string} + * @api stable + */ + get name() { + return this.name_; + } + + /** + * This function gets metadata plugin + * + * @public + * @function + * @api stable + */ + getMetadata() { + return this.metadata_; + } + + /** + * Get the API REST Parameters of the plugin + * + * @function + * @public + * @api + */ + getAPIRest() { + return `${this.name}=${this.position}*!${this.collapsed}*!${this.collapsible}*!${this.modeViz}*!${this.enabledKeyFunctions}*!${this.showCursors}*!${this.mirrorLayers}*!${this.defaultBaseLyrs}*!${this.interface}*!${this.showTOC}`; + } + + /** + * Activate plugin + * + * @function + * @public + * @api + */ + activate() { + this.control_.activate(); + } + + /** + * Desactivate plugin + * + * @function + * @public + * @api + */ + deactivate() { + this.control_.deactivate(); + } + + +} diff --git a/src/facade/js/mirrorpanelcontrol.js b/src/facade/js/mirrorpanelcontrol.js new file mode 100644 index 0000000..8dc0d9a --- /dev/null +++ b/src/facade/js/mirrorpanelcontrol.js @@ -0,0 +1,401 @@ +/** + * @module M/control/MirrorpanelControl + */ + +import MirrorpanelImplControl from 'impl/mirrorpanelcontrol'; +import template from 'templates/mirrorpanel'; +import { getValue as getValueTranslate } from './i18n/language'; + +export default class MirrorpanelControl extends M.Control { + /** + * @classdesc + * Main constructor of the class. Creates a PluginControl + * control + * + * @constructor + * @extends {M.Control} + * @api stable + */ + constructor(values) { + // 1. checks if the implementation can create PluginControl + if (M.utils.isUndefined(MirrorpanelImplControl)) { + M.exception('La implementación usada no puede crear controles MirrorpanelControl'); + } + // 2. implementation of this control + const impl = new MirrorpanelImplControl(); + super(impl, 'Mirrorpanel'); + + /** + * Template + * @public + * @type { HTMLElement } + */ + this.template = null; + + /** + * Visual mode + * @private + * @type {Number} + */ + this.modeViz = values.modeViz; + + /** + * Mirror maps with plugins + * @private + * @type {boolean} + */ + this.showCursors = values.showCursors; + + /** + * Defining mirror maps variables + */ + this.mapL = { A: null, B: null, C: null, D: null, } + this.lyrCursor = { A: null, B: null, C: null, D: null, } + this.featureLyrCursor = { A: null, B: null, C: null, D: null, } + + /** + * Defining cursor style + */ + this.styleCursor = new M.style.Point({ + icon: { + form: M.style.form.CIRCLE, + fontsize: 0.5, + radius: 5, + rotation: 0, + rotate: false, + offset: [0, 0], + color: 'black', + fill: 'red', + gradientcolor: '#088A85', + opacity: 0.8 + } + }); + + /** + * Default layers for mirror maps + * @public + * @public {Array} + */ + this.defaultBaseLyrs = values.defaultBaseLyrs; + + /** + * All layers + * @public + * @public {Array} + */ + this.mirrorLayers = values.mirrorLayers; + + /** + * Enable layerswitcher control + * @public + * @public {Array} + */ + this.showTOC = values.showTOC; + + this.createMapContainers(); + } + + + /** + * This function creates the view + * + * @public + * @function + * @param {M.Map} map to add the control + * @api stable + */ + createView(map) { + if (!M.template.compileSync) { + M.template.compileSync = (string, options) => { + let templateCompiled; + let templateVars = {}; + let parseToHtml; + if (!M.utils.isUndefined(options)) { + templateVars = M.utils.extends(templateVars, options.vars); + parseToHtml = options.parseToHtml; + } + const templateFn = Handlebars.compile(string); + const htmlText = templateFn(templateVars); + if (parseToHtml !== false) { + templateCompiled = M.utils.stringToHtml(htmlText); + } else { + templateCompiled = htmlText; + } + return templateCompiled; + }; + } + + this.mapL['A'] = map; + if (this.mirrorLayers.length > 0) { + this.mapL['A'].addLayers(this.mirrorLayers); + this.mapL['A'].getLayers().forEach((l) => { + if (l.zindex_ !== 0) { l.setVisible(false); } + }); + } + if (this.showCursors) { this.addLayerCursor('A'); } + return new Promise((success, fail) => { + let templateOptions = ''; + templateOptions = { + jsonp: true, + vars: { + translations: { + title: getValueTranslate('title'), + modViz0: getValueTranslate('modViz0'), + modViz1: getValueTranslate('modViz1'), + modViz2: getValueTranslate('modViz2'), + modViz3: getValueTranslate('modViz3'), + modViz4: getValueTranslate('modViz4'), + modViz5: getValueTranslate('modViz5'), + modViz6: getValueTranslate('modViz6'), + modViz7: getValueTranslate('modViz7'), + modViz8: getValueTranslate('modViz8'), + modViz9: getValueTranslate('modViz9') + } + } + }; + + this.template = M.template.compileSync(template, templateOptions); + + // Button's click events + this.template.querySelectorAll('button[id^="set-mirror-"]') + .forEach((button, modeViz) => { + button.addEventListener('click', evt => { + this.manageVisionPanelByCSSGrid(modeViz); + }) + }); + + // Apply default vision + this.manageVisionPanelByCSSGrid(this.modeViz); + success(this.template); + }); + + } + + /** + * This function is called on the control activation + * + * @public + * @function + * @api stable + */ + activate() { + super.activate(); + } + /** + * This function is called on the control deactivation + * + * @public + * @function + * @api stable + */ + deactivate() { + super.deactivate(); + } + + /** + * Initial configurations for applying CSS grid. + * + */ + createMapContainers() { + const bigContainer = document.createElement('div'); + bigContainer.id = "lienzo"; + bigContainer.classList.add('mirrorpanel-grid'); + + const mapjsA = document.getElementById("mapjs") || document.getElementById("map"); + document.body.insertBefore(bigContainer, mapjsA); + mapjsA.classList.add('mirror1'); + bigContainer.appendChild(mapjsA); + + const mapjsB = document.createElement('div'); + mapjsB.id = "mapjsB"; + mapjsB.classList.add('mirror2'); + bigContainer.appendChild(mapjsB); + + const mapjsC = document.createElement('div'); + mapjsC.id = "mapjsC"; + mapjsC.classList.add('mirror3'); + bigContainer.appendChild(mapjsC); + + const mapjsD = document.createElement('div'); + mapjsD.id = "mapjsD"; + mapjsD.classList.add('mirror4'); + bigContainer.appendChild(mapjsD); + } + + /** + * This function shows/hides panel for differents viz options. + * The mirror maps are launched from here + * + */ + manageVisionPanelByCSSGrid(modeViz) { + let oldModeViz = this.modeViz; + let map0 = document.getElementById('mapjs') || document.getElementById('map'); + map0.style.display = 'none'; + document.getElementById('mapjsB').style.display = 'none'; + document.getElementById('mapjsC').style.display = 'none'; + document.getElementById('mapjsD').style.display = 'none'; + this.template.querySelector('#set-mirror-' + oldModeViz).classList.remove('buttom-pressed'); + + for (let i = 0; i < 10; i++) { + document.getElementById('lienzo').classList.remove('modeViz' + i); + } + document.getElementById('lienzo').classList.add('modeViz' + modeViz); + + //Create map objects by modeviz + if ([1, 2].includes(modeViz)) { + if (this.mapL['B'] == null) { + this.createMapObjects('B');//Create MapB + } + } + if ([3, 7, 8, 9].includes(modeViz)) { + if (this.mapL['B'] == null) { + this.createMapObjects('B');//Create MapB + } + if (this.mapL['C'] == null) { + this.createMapObjects('C');//Create MapC + } + } + if ([4, 5, 6].includes(modeViz)) { + if (this.mapL['B'] == null) { + this.createMapObjects('B');//Create MapB + } + if (this.mapL['C'] == null) { + this.createMapObjects('C');//Create MapC + } + if (this.mapL['D'] == null) { + this.createMapObjects('D');//Create MapD + } + } + + this.modeViz = modeViz; + this.template.querySelector('#set-mirror-' + modeViz).classList.add('buttom-pressed'); + this.map_.refresh(); + if (this.mapL['B'] !== null) { this.mapL['B'].refresh(); } + if (this.mapL['C'] !== null) { this.mapL['C'].refresh(); } + if (this.mapL['D'] !== null) { this.mapL['D'].refresh(); } + } + + /** + * Create mirror map object synchro with the main map + */ + createMapObjects(mapLyr) { + let defLyr = null; + switch (mapLyr) { + case 'B': + if (this.defaultBaseLyrs[1]) defLyr = this.defaultBaseLyrs[0]; + break; + case 'C': + if (this.defaultBaseLyrs[2]) defLyr = this.defaultBaseLyrs[1]; + break; + case 'D': + if (this.defaultBaseLyrs[3]) defLyr = this.defaultBaseLyrs[2]; + break; + default: + defLyr = this.map_.getLayers()[0].setMap(this); + break; + } + this.mapL[mapLyr] = M.map({ + container: 'mapjs' + mapLyr, + layers: defLyr, + controls: this.showTOC ? ['layerswitcher'] : '', + center: this.map_.getCenter(), + projection: this.map_.getProjection().code + '*' + this.map_.getProjection().units, + zoom: this.map_.getZoom(), + }); + this.mapL[mapLyr].getMapImpl().setView(this.map_.getMapImpl().getView()); + + if (this.showCursors) { this.addLayerCursor(mapLyr); } + if (this.mirrorLayers.length > 0) { + this.mapL[mapLyr].addLayers(this.mirrorLayers); + this.mapL[mapLyr].getLayers().forEach((l) => { + if (l.zindex_ !== 0) { l.setVisible(false); } + }); + } + this.mapL[mapLyr].refresh(); + } + + /** + * Adding a layer for cursor on Map + */ + addLayerCursor(mapLyr) { + // Cursor Layer + this.lyrCursor[mapLyr] = new M.layer.Vector({ + name: 'Coordenadas centro ' + mapLyr, + }, { displayInLayerSwitcher: false }); + + this.featureLyrCursor[mapLyr] = new M.Feature('Center' + mapLyr, { + type: 'Feature', + properties: {}, + geometry: { + type: 'Point', + coordinates: this.mapL[mapLyr].getCenter(), + }, + }); + + this.lyrCursor[mapLyr].addFeatures([this.featureLyrCursor[mapLyr]]); + this.lyrCursor[mapLyr].setStyle(this.styleCursor); + this.lyrCursor[mapLyr].setZIndex(5000); + this.mapL[mapLyr].addLayers(this.lyrCursor[mapLyr]); + + this.mapL[mapLyr].getMapImpl().on('pointermove', (event) => { + this.lyrCursor[mapLyr].setVisible(false); + Object.keys(this.featureLyrCursor).forEach(k => { + if (this.mapL[k]) { + this.mapL[k].getMapImpl().setView(this.mapL[mapLyr].getMapImpl().getView()); + } + if (k != mapLyr) { + if (this.featureLyrCursor[k] !== null) { + this.lyrCursor[k].setVisible(true); + this.featureLyrCursor[k].setGeometry({ + type: 'Point', + coordinates: event.coordinate, + }); + } + } + }) + }); + + } + + /** + * This function is called to remove the effects + * + * @public + * @function + * @api stable + */ + removeMaps() { + this.mapL['B'] = null; + this.mapL['C'] = null; + this.mapL['D'] = null; + } + + destroyMapsContainer() { + // Remove mirrors containers + document.getElementById("mapjsB").remove(); + document.getElementById("mapjsC").remove(); + document.getElementById("mapjsD").remove(); + + // Take the main map out of the container + const lienzo = document.getElementById("lienzo"); + const mapjsA = document.getElementById("mapjs") || document.getElementById("map"); + mapjsA.style.display = "block"; + mapjsA.classList.remove('mirror1'); + document.body.insertBefore(mapjsA, lienzo); + + // Load the main container + document.getElementById("lienzo").remove(); + } + + /** + * This function compares controls + * + * @public + * @function + * @param {M.Control} control to compare + * @api stable + */ + equals(control) { + return control instanceof MirrorpanelControl; + } +} diff --git a/src/impl/ol/js/mirrorpanelcontrol.js b/src/impl/ol/js/mirrorpanelcontrol.js new file mode 100644 index 0000000..99060ff --- /dev/null +++ b/src/impl/ol/js/mirrorpanelcontrol.js @@ -0,0 +1,24 @@ +/** + * @module M/impl/control/MirrorpanelControl + */ +export default class MirrorpanelControl extends M.impl.Control { + /** + * This function adds the control to the specified map + * + * @public + * @function + * @param {M.Map} map to add the plugin + * @param {HTMLElement} html of the plugin + * @api stable + */ + addTo(map, html) { + // obtengo la interacción por defecto del dblclick para manejarla + const olMap = map.getMapImpl(); + olMap.getInteractions().forEach((interaction) => { + if (interaction instanceof ol.interaction.DoubleClickZoom) { + this.dblClickInteraction_ = interaction; + } + }); + super.addTo(map, html); + } +} diff --git a/src/templates/mirrorpanel.html b/src/templates/mirrorpanel.html new file mode 100644 index 0000000..b450878 --- /dev/null +++ b/src/templates/mirrorpanel.html @@ -0,0 +1,21 @@ +
+
{{translations.title}}
+
+
+ + + + + +
+
+ + + + + +
+ +
+ +
diff --git a/task/create-entrypoint.js b/task/create-entrypoint.js new file mode 100644 index 0000000..de3cf32 --- /dev/null +++ b/task/create-entrypoint.js @@ -0,0 +1,67 @@ +const path = require('path'); +const slash = require('slash'); +const fs = require('fs-extra'); +const SRC_PATH = path.resolve(__dirname, '..', 'src'); +const DIST_PATH = path.resolve(__dirname, '..', 'dist'); +const FACADE_PATH = path.resolve(SRC_PATH, 'facade', 'js'); +const IMPL_PATH = path.resolve(SRC_PATH, 'impl', 'ol', 'js'); + +const files = []; +const namespaces = []; +const uniqueNS = []; +let imports = ''; +let exportedClasses = ''; +let createNS = ''; + +const getAbsolutePath = (fileNames, fullPath) => { + const absolutePaths = fileNames.map(fileName => path.resolve(fullPath, fileName)); + absolutePaths.forEach((absolutePath) => { + if (fs.lstatSync(absolutePath).isDirectory() === true) { + getAbsolutePath(fs.readdirSync(absolutePath), absolutePath); + } else if (/.js$/.test(absolutePath)) { + files.push(absolutePath); + } + }); +}; + +const facadeFiles = fs.readdirSync(FACADE_PATH); +const implFiles = fs.readdirSync(IMPL_PATH); +getAbsolutePath(facadeFiles, FACADE_PATH); +getAbsolutePath(implFiles, IMPL_PATH); + +files.forEach((file) => { + const match = fs.readFileSync(file, 'utf8').match(/@module.*/); + if (match !== null) { + const namespace = match[0].replace(/@module (.*)/, '$1'); + namespaces.push({ + alias: namespace.replace(/\//g, '$'), + namespace: namespace.replace(/\//g, '.'), + path: slash(file), + }); + } +}); + +namespaces.forEach((namespace) => { + const partitions = namespace.namespace.split('.'); + for (let i = 2; i < partitions.length; i += 1) { + const partition = partitions.slice(0, i).join('.'); + if (uniqueNS.includes(partition) === false) { + uniqueNS.push(partition); + } + } +}); + +namespaces.forEach((namespace) => { + imports += `import ${namespace.alias} from '${namespace.path.replace(/(.*)\.js/, '$1')}';\n`; + exportedClasses += `window.${namespace.namespace} = ${namespace.alias};\n`; +}); + +uniqueNS.forEach((ns) => { + createNS += `if (!window.${ns}) window.${ns} = {};\n`; +}); + +const contentEntryPoint = `${imports}\n${createNS}${exportedClasses}`; + +fs.writeFileSync(path.join(SRC_PATH, 'index.js'), contentEntryPoint); +fs.removeSync(DIST_PATH); +fs.ensureDirSync(DIST_PATH); diff --git a/test/dev.html b/test/dev.html new file mode 100644 index 0000000..a08c477 --- /dev/null +++ b/test/dev.html @@ -0,0 +1,28 @@ + + + + + + + + + Mirrorpanel TEST + + + + + +
+ + + + + + diff --git a/test/prod.html b/test/prod.html new file mode 100644 index 0000000..7dd2018 --- /dev/null +++ b/test/prod.html @@ -0,0 +1,45 @@ + + + + + + + + + Mirrorpanel TEST + + + + + + + +
+ + + + + + + \ No newline at end of file diff --git a/test/test.js b/test/test.js new file mode 100644 index 0000000..13cd74e --- /dev/null +++ b/test/test.js @@ -0,0 +1,82 @@ +import Mirrorpanel from 'facade/mirrorpanel'; //Importación del plugin que desarrollamos para trabajar + +M.language.setLang('es'); //Español +//M.language.setLang('en');//Inglés + +const map = M.map({ + container: 'mapjs', + center: { + x: -667143.31, + y: 4493011.77, + }, + controls: ['scale', 'location', 'layerswitcher'], + projection: "EPSG:3857*m", + zoom: 8, +}); + +let capasPNOA = [ + 'WMS*PNOA 2015*https://www.ign.es/wms/pnoa-historico*PNOA2015', + 'WMS*PNOA 2016*https://www.ign.es/wms/pnoa-historico*PNOA2016', + 'WMS*PNOA 2017*https://www.ign.es/wms/pnoa-historico*PNOA2017', + 'WMS*PNOA 2018*https://www.ign.es/wms/pnoa-historico*PNOA2018', +]; + +let defaultBaseLyrs = [ + new M.layer.WMTS({ + url: 'http://www.ign.es/wmts/ign-base?', + name: 'IGNBaseTodo', + legend: 'Mapa IGN', + matrixSet: 'GoogleMapsCompatible', + transparent: false, + displayInLayerSwitcher: false, + queryable: false, + visible: true, + format: 'image/jpeg', + }), + new M.layer.WMTS({ + url: 'http://www.ign.es/wmts/pnoa-ma?', + name: 'OI.OrthoimageCoverage', + legend: 'Imagen (PNOA)', + matrixSet: 'GoogleMapsCompatible', + transparent: false, + displayInLayerSwitcher: false, + queryable: false, + visible: true, + format: 'image/jpeg', + }), + new M.layer.WMTS({ + url: 'https://wmts-mapa-lidar.idee.es/lidar?', + name: 'EL.GridCoverageDSM', + legend: 'Modelo Digital de Superficies LiDAR', + matrixSet: 'GoogleMapsCompatible', + transparent: false, + displayInLayerSwitcher: false, + queryable: false, + visible: true, + format: 'image/png', + }), + new M.layer.WMTS({ + url: 'http://www.ideandalucia.es/geowebcache/service/wmts?', + name: 'orto_2010-11', + legend: 'orto_2010-11', + matrixSet: 'SIG-C:25830', + transparent: false, + displayInLayerSwitcher: false, + queryable: false, + visible: true, + format: 'image/png', + }) +] + +const mpMirrorPanel = new Mirrorpanel({ + position: 'TR', + collapsible: true, // El botón para desplegar/replegar el plugin no aparece (false) o sí aparece(true) + collapsed: false, // El panel del plugin se muestra desplegado (false) o replegado (true) + modeViz: 0, + mirrorLayers: capasPNOA, + defaultBaseLyrs: defaultBaseLyrs, // Array de capas para los mapas espejo en formato StringAPICNIG + enabledKeyFunctions: true, // Están habilitadas los comandos por teclado + showCursors: true, // Se muestran los cursores +}); + +map.addPlugin(mpMirrorPanel); \ No newline at end of file diff --git a/webpack-config/GenerateVersionPlugin.js b/webpack-config/GenerateVersionPlugin.js new file mode 100644 index 0000000..e55e424 --- /dev/null +++ b/webpack-config/GenerateVersionPlugin.js @@ -0,0 +1,52 @@ +const pathmodule = require('path'); +const fs = require('fs'); +/** + * Webpack plugin that allows overwrite functions definitions after import. + * This plugin is directly related to the class src/impl/ol/js/patches.js, which is used to + * overwrite functions of openlayers that we can not access by inheritance of classes. + * @class AllowMutateEsmExports + */ +class GenerateVersionPlugin { + constructor(opt) { + this.version = opt.version; + this.regex = opt.regex; + this.fileName = opt.fileName; + this.aliasRoot = opt.aliasRoot; + } + /** + * This function apply the logic plugin. + * @function + */ + apply(compiler) { + compiler.hooks.done.tap('GenerateVersionPlugin', (stats) => { + const { path } = stats.compilation.options.output; + stats.compilation.chunks.forEach((chunk) => { + chunk.files.forEach((file, index) => { + const basename = pathmodule.basename(file); + const version = this.version || this.geExecuteCB(index, stats); + let replacePath; + if (this.regex instanceof RegExp) { + replacePath = basename.replace(this.regex, `$1-${version}$2`); + } + const realPath = pathmodule.resolve(path, file); + const newPath = pathmodule.join(pathmodule.dirname(realPath), replacePath); + fs.copyFileSync(realPath, newPath); + }); + }); + }); + } + + /** + * @function + */ + geExecuteCB(index, stats) { + const entry = Object.keys(stats.compilation.options.entry)[index]; + const name = entry.split('/').slice(-1)[0]; + const context = stats.compilation.options.resolve.alias[this.aliasRoot]; + const absolutePath = pathmodule.resolve(context, name, this.fileName); + const version = JSON.parse(fs.readFileSync(absolutePath)).version; + return version; + } +} + +module.exports = GenerateVersionPlugin; diff --git a/webpack-config/webpack.development.config.js b/webpack-config/webpack.development.config.js new file mode 100644 index 0000000..8b569e7 --- /dev/null +++ b/webpack-config/webpack.development.config.js @@ -0,0 +1,62 @@ +const path = require('path'); +const webpack = require('webpack'); + +module.exports = { + mode: 'development', + entry: path.resolve(__dirname, '..', 'test', 'test.js'), + resolve: { + alias: { + templates: path.resolve(__dirname, '../src/templates'), + assets: path.resolve(__dirname, '../src/facade/assets'), + impl: path.resolve(__dirname, '../src/impl/ol/js'), + facade: path.resolve(__dirname, '../src/facade/js'), + }, + extensions: ['.wasm', '.mjs', '.js', '.json', '.css', '.hbs', '.html'], + }, + module: { + rules: [ + { + test: /\.js$/, + exclude: /(node_modules\/(?!ol)|bower_components)/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'], + }, + }, + }, + { + test: /\.js$/, + loader: 'eslint-loader', + exclude: [/node_modules/, /lib/, /test/, /dist/], + }, + { + test: [/\.hbs$/, /\.html$/], + loader: 'html-loader', + exclude: /node_modules/, + }, + { + test: /\.css$/, + loader: 'style-loader!css-loader', + exclude: [/node_modules/], + }, + { + test: /\.(woff|woff2|eot|ttf|svg)$/, + exclude: /node_modules/, + loader: 'url-loader?name=fonts/[name].[ext]', + }], + }, + plugins: [ + new webpack.HotModuleReplacementPlugin(), + ], + devServer: { + hot: true, + open: true, + port: 6123, + openPage: 'test/dev.html', + watchOptions: { + poll: 1000, + }, + }, + devtool: 'eval-source-map', +}; diff --git a/webpack-config/webpack.production.config.js b/webpack-config/webpack.production.config.js new file mode 100644 index 0000000..9a8fcf4 --- /dev/null +++ b/webpack-config/webpack.production.config.js @@ -0,0 +1,90 @@ +const path = require('path'); +const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); +const GenerateVersionPlugin = require('./GenerateVersionPlugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const CopywebpackPlugin = require('copy-webpack-plugin'); + +const PJSON_PATH = path.resolve(__dirname, '..', 'package.json'); +const pjson = require(PJSON_PATH); + +module.exports = { + mode: 'production', + entry: { + 'mirrorpanel.ol.min': path.resolve(__dirname, '..', 'src', 'index.js'), + }, + output: { + path: path.resolve(__dirname, '..', 'dist'), + filename: '[name].js', + }, + resolve: { + alias: { + templates: path.resolve(__dirname, '../src/templates'), + assets: path.resolve(__dirname, '../src/facade/assets'), + impl: path.resolve(__dirname, '../src/impl/ol/js'), + facade: path.resolve(__dirname, '../src/facade/js'), + }, + extensions: ['.wasm', '.mjs', '.js', '.json', '.css', '.hbs', '.html'], + }, + module: { + rules: [{ + test: /\.js$/, + exclude: /(node_modules\/(?!ol)|bower_components)/, + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-env'], + }, + }, + }, + { + test: /\.js$/, + loader: 'eslint-loader', + exclude: /node_modules/, + }, + { + test: [/\.hbs$/, /\.html$/], + loader: 'html-loader', + exclude: /node_modules/, + }, + { + test: /\.css$/, + loader: MiniCssExtractPlugin.loader, + exclude: /node_modules/, + }, { + test: /\.css$/, + loader: 'css-loader', + exclude: /node_modules/, + + }, + { + test: /\.(woff|woff2|eot|ttf|svg)$/, + exclude: /node_modules/, + loader: 'url-loader?name=fonts/[name].[ext]', + } + ], + }, + optimization: { + noEmitOnErrors: true, + minimizer: [ + new OptimizeCssAssetsPlugin(), + new TerserPlugin({ + sourceMap: true, + }), + ], + }, + plugins: [ + // new GenerateVersionPlugin({ + // version: pjson.version, + // regex: /([A-Za-z]+)(\..*)/, + // }), + new MiniCssExtractPlugin({ + filename: '[name].css', + }), + new CopywebpackPlugin([{ + from: 'src/api.json', + to: 'api.json', + }]), + ], + devtool: 'source-map', +};