From cb2597278900234cbba454729d1dd86aa919a07c Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Tue, 16 Aug 2016 20:43:40 +0200 Subject: [PATCH 01/10] add leaflet layers --- Maps_Settings.php | 62 +- i18n/en.json | 1 + i18n/qqq.json | 1 + includes/Maps_DisplayMapRenderer.php | 7 + includes/services/Leaflet/Leaflet.php | 13 + includes/services/Leaflet/Maps_Leaflet.php | 17 + includes/services/Leaflet/jquery.leaflet.js | 18 +- .../Leaflet/leaflet-providers/.eslintrc | 39 ++ .../Leaflet/leaflet-providers/.gitignore | 1 + .../Leaflet/leaflet-providers/.mversionrc | 8 + .../Leaflet/leaflet-providers/.travis.yml | 8 + .../Leaflet/leaflet-providers/CHANGELOG.md | 46 ++ .../Leaflet/leaflet-providers/CONTRIBUTING.md | 10 + .../Leaflet/leaflet-providers/README.md | 63 ++ .../Leaflet/leaflet-providers/bower.json | 25 + .../leaflet-providers/css/gh-fork-ribbon.css | 127 ++++ .../css/gh-fork-ribbon.ie.css | 68 ++ .../Leaflet/leaflet-providers/index.html | 94 +++ .../leaflet-providers/leaflet-providers.js | 639 ++++++++++++++++++ .../Leaflet/leaflet-providers/license.md | 9 + .../Leaflet/leaflet-providers/package.json | 45 ++ .../preview/https-support.js | 57 ++ .../leaflet-providers/preview/index.html | 90 +++ .../leaflet-providers/preview/layer-bounds.js | 63 ++ .../leaflet-providers/preview/preview.js | 227 +++++++ .../leaflet-providers/preview/shared.js | 63 ++ .../preview/test-bounds.html | 87 +++ .../preview/test-https-support.html | 79 +++ .../leaflet-providers/tests/index.html | 44 ++ .../Leaflet/leaflet-providers/tests/test.js | 99 +++ 30 files changed, 2107 insertions(+), 3 deletions(-) create mode 100644 includes/services/Leaflet/leaflet-providers/.eslintrc create mode 100644 includes/services/Leaflet/leaflet-providers/.gitignore create mode 100644 includes/services/Leaflet/leaflet-providers/.mversionrc create mode 100644 includes/services/Leaflet/leaflet-providers/.travis.yml create mode 100644 includes/services/Leaflet/leaflet-providers/CHANGELOG.md create mode 100644 includes/services/Leaflet/leaflet-providers/CONTRIBUTING.md create mode 100644 includes/services/Leaflet/leaflet-providers/README.md create mode 100644 includes/services/Leaflet/leaflet-providers/bower.json create mode 100644 includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.css create mode 100644 includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.ie.css create mode 100644 includes/services/Leaflet/leaflet-providers/index.html create mode 100644 includes/services/Leaflet/leaflet-providers/leaflet-providers.js create mode 100644 includes/services/Leaflet/leaflet-providers/license.md create mode 100644 includes/services/Leaflet/leaflet-providers/package.json create mode 100644 includes/services/Leaflet/leaflet-providers/preview/https-support.js create mode 100644 includes/services/Leaflet/leaflet-providers/preview/index.html create mode 100644 includes/services/Leaflet/leaflet-providers/preview/layer-bounds.js create mode 100644 includes/services/Leaflet/leaflet-providers/preview/preview.js create mode 100644 includes/services/Leaflet/leaflet-providers/preview/shared.js create mode 100644 includes/services/Leaflet/leaflet-providers/preview/test-bounds.html create mode 100644 includes/services/Leaflet/leaflet-providers/preview/test-https-support.html create mode 100644 includes/services/Leaflet/leaflet-providers/tests/index.html create mode 100644 includes/services/Leaflet/leaflet-providers/tests/test.js diff --git a/Maps_Settings.php b/Maps_Settings.php index 9b62a3bb0..a3daa7f52 100644 --- a/Maps_Settings.php +++ b/Maps_Settings.php @@ -250,7 +250,7 @@ 'osm-cyclemap' ]; - // The difinitions for the layers that should be available for the user. + // The definitions for the layers that should be available for the user. $GLOBALS['egMapsOLAvailableLayers'] = [ //'google' => array( 'OpenLayers.Layer.Google("Google Streets")' ), @@ -301,5 +301,65 @@ // user does not provide one. $GLOBALS['egMapsLeafletZoom'] = 14; + // String. The default layer for Leaflet. This value will only be + // used when the user does not provide one. + $GLOBALS['egMapsLeafletLayer'] = 'OpenStreetMap'; + + $GLOBALS['egMapsLeafletOverlayLayers'] = [ + + ]; + + // The definitions for the layers that should be available for the user. + $GLOBALS['egMapsLeafletAvailableLayers'] = [ + 'OpenStreetMap', + 'OpenStreetMap.DE', + 'OpenStreetMap.BlackAndWhite', + 'OpenStreetMap.HOT', + 'Thunderforest.OpenCycleMap', + 'Thunderforest.Transport', + 'Thunderforest.Landscape', + 'Hydda.Full', + 'MapBox', + 'Stamen.Toner', + 'Stamen.Terrain', + 'Stamen.Watercolor', + 'Esri.WorldStreetMap', + 'Esri.DeLorme', + 'Esri.WorldTopoMap', + 'Esri.WorldImagery', + 'Esri.WorldTerrain', + 'Esri.WorldShadedRelief', + 'Esri.WorldPhysical', + 'Esri.OceanBasemap', + 'Esri.NatGeoWorldMap', + 'Esri.WorldGrayCanvas', + 'MapQuestOpen', + ]; + + $GLOBALS['egMapsLeafletAvailableOverlayLayers'] = [ + 'OpenSeaMap', + 'OpenWeatherMap.Clouds', + 'OpenWeatherMap.CloudsClassic', + 'OpenWeatherMap.Precipitation', + 'OpenWeatherMap.PrecipitationClassic', + 'OpenWeatherMap.Rain', + 'OpenWeatherMap.RainClassic', + 'OpenWeatherMap.Pressure', + 'OpenWeatherMap.PressureContour', + 'OpenWeatherMap.Wind', + 'OpenWeatherMap.Temperature', + 'OpenWeatherMap.Snow', + ]; + + $GLOBALS['egMapsLeafletLayersApiKeys'] = [ + 'MapBox' => '', + 'MapQuestOpen' => '', + ]; + + // Layer dependencies + $GLOBALS['egMapsLeafletLayerDependencies'] = [ + 'MapQuestOpen' => "", + ]; + $GLOBALS['egMapsGlobalJSVars'] = []; diff --git a/i18n/en.json b/i18n/en.json index d117662c6..ee9dc748d 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -119,6 +119,7 @@ "maps_googlemaps3": "Google Maps v3", "maps_leaflet": "Leaflet", "maps-leaflet-par-defzoom": "Allows setting the default zoom level of the map.", + "maps-leaflet-par-layer": "The layer that will be shown when the map loads.", "maps-leaflet-par-maxclusterradius": "The maximum radius that a cluster will cover from the central marker (in pixels).", "maps-leaflet-par-clusterspiderfy": "When you click a cluster at the bottom zoom level we spiderfy it so you can see all of its markers.", "maps_openlayers": "OpenLayers", diff --git a/i18n/qqq.json b/i18n/qqq.json index 4ca45db57..e6e795584 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -129,6 +129,7 @@ "maps_googlemaps3": "Lable for a result format on SMW's special page \"Ask\".\n\n{{optional}}", "maps_leaflet": "This is a field label.\n\n{{optional}}", "maps-leaflet-par-defzoom": "{{maps-par|leaflet|defzoom}}", + "maps-leaflet-par-layer": "{{maps-par|leaflet|layer}}", "maps-leaflet-par-maxclusterradius": "{{maps-par|leaflet|maxclusterradius}}", "maps-leaflet-par-clusterspiderfy": "{{maps-par|leaflet|clusterspiderfy}}", "maps_openlayers": "Lable for a result format on SMW's special page \"Ask\".\n\n{{optional}}", diff --git a/includes/Maps_DisplayMapRenderer.php b/includes/Maps_DisplayMapRenderer.php index d4758f30e..8268f0c90 100644 --- a/includes/Maps_DisplayMapRenderer.php +++ b/includes/Maps_DisplayMapRenderer.php @@ -145,6 +145,13 @@ protected function handleMarkerData( array &$params, Parser $parser ) { if ( $params['mappingservice'] === 'openlayers' ) { $params['layers'] = self::evilOpenLayersHack( $params['layers'] ); + } else if ( $params['mappingservice'] === 'leaflet' ) { + global $egMapsLeafletLayerDependencies; + $layerDependencies = []; + $layerDependencies[] = $egMapsLeafletLayerDependencies['MapQuestOpen']; + MapsMappingServices::getServiceInstance( 'leaflet' )->addLayerDependencies( + array_unique( $layerDependencies ) + ); } } diff --git a/includes/services/Leaflet/Leaflet.php b/includes/services/Leaflet/Leaflet.php index a993796a8..52eae723e 100644 --- a/includes/services/Leaflet/Leaflet.php +++ b/includes/services/Leaflet/Leaflet.php @@ -77,6 +77,19 @@ 'MarkerCluster.css', ], ]; + + $wgResourceModules['ext.maps.leaflet.providers'] = [ + 'localBasePath' => __DIR__ . '/leaflet-providers', + 'remoteExtPath' => end( $pathParts ) . '/leaflet-providers', + 'group' => 'ext.maps', + 'targets' => [ + 'mobile', + 'desktop' + ], + 'scripts' => [ + 'leaflet-providers.js', + ], + ]; } ); /** diff --git a/includes/services/Leaflet/Maps_Leaflet.php b/includes/services/Leaflet/Maps_Leaflet.php index 431d09ef9..be2e0018a 100644 --- a/includes/services/Leaflet/Maps_Leaflet.php +++ b/includes/services/Leaflet/Maps_Leaflet.php @@ -25,6 +25,8 @@ public function __construct( $serviceName ) { * @since 3.0 */ public function addParameterInfo( array &$params ) { + global $GLOBALS; + $params['zoom'] = [ 'type' => 'integer', 'range' => [ 0, 20 ], @@ -39,6 +41,21 @@ public function addParameterInfo( array &$params ) { 'message' => 'maps-leaflet-par-defzoom' ]; + $params['layer'] = [ + 'type' => 'string', + 'values' => $GLOBALS['egMapsLeafletAvailableLayers'], + 'default' => $GLOBALS['egMapsLeafletLayer'], + 'message' =>'maps-leaflet-par-layer', + ]; + + $params['overlaylayers'] = [ + 'type' => 'string', + 'values' => $GLOBALS['egMapsLeafletAvailableOverlayLayers'], + 'default' => $GLOBALS['egMapsLeafletOverlayLayers'], + 'message' =>'maps-leaflet-par-overlaylayers', // todo: add to i18n + 'islist' => true, + ]; + $params['resizable'] = [ 'type' => 'boolean', 'default' => $GLOBALS['egMapsResizableByDefault'], diff --git a/includes/services/Leaflet/jquery.leaflet.js b/includes/services/Leaflet/jquery.leaflet.js index aa46a5e91..496f0e749 100644 --- a/includes/services/Leaflet/jquery.leaflet.js +++ b/includes/services/Leaflet/jquery.leaflet.js @@ -252,9 +252,19 @@ this.map = map; // add an OpenStreetMap tile layer - L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { + var layerOptions = { attribution: '© OpenStreetMap contributors' - }).addTo(map); + }; + if (options.layer !== 'MapQuestOpen') { + L.tileLayer.provider(options.layer, layerOptions).addTo(map); + } else { + //MQ.TileLayer(layerOptions).addTo(map) + } + + $.each(options.overlaylayers, function(index, overlaylayer) { + console.log(overlaylayer); + L.tileLayer.provider(overlaylayer).addTo(_this.map); + }); if (options.resizable) { //TODO: Fix moving map when resized @@ -334,6 +344,7 @@ this.getDependencies = function ( options ) { var dependencies = []; + dependencies.push( 'ext.maps.leaflet.providers' ); if (options.enablefullscreen) { dependencies.push( 'ext.maps.leaflet.fullscreen' ); } @@ -343,6 +354,9 @@ if (options.markercluster) { dependencies.push( 'ext.maps.leaflet.markercluster' ); } + /*if (options.layer === 'MapQuestOpen') { + // todo: load dependency + }*/ return dependencies; }; diff --git a/includes/services/Leaflet/leaflet-providers/.eslintrc b/includes/services/Leaflet/leaflet-providers/.eslintrc new file mode 100644 index 000000000..62f190384 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/.eslintrc @@ -0,0 +1,39 @@ +{ + "rules": { + "camelcase": 2, + "quotes": [2, "single", "avoid-escape"], + "no-mixed-spaces-and-tabs": [2, "smart-tabs"], + "space-before-function-paren": 2, + "space-in-parens": 2, + "object-curly-spacing": 2, + "array-bracket-spacing": 2, + "computed-property-spacing": 2, + "space-before-blocks": 2, + "keyword-spacing": 2, + "no-lonely-if": 2, + "comma-style": 2, + "no-underscore-dangle": 0, + "no-constant-condition": 0, + "no-multi-spaces": 0, + "strict": 0, + "key-spacing": 0, + "no-shadow": 0, + "no-unused-vars": 2, + "eqeqeq": 2 + }, + "globals": { + "L": true, + "module": false, + "define": false, + "require": true + }, + "plugins": [ + "html" + ], + "settings": { + "html/report-bad-indent": 2 + }, + "env": { + "browser": true + } +} diff --git a/includes/services/Leaflet/leaflet-providers/.gitignore b/includes/services/Leaflet/leaflet-providers/.gitignore new file mode 100644 index 000000000..0e6b7ded0 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/.gitignore @@ -0,0 +1 @@ +leaflet-providers.min.js diff --git a/includes/services/Leaflet/leaflet-providers/.mversionrc b/includes/services/Leaflet/leaflet-providers/.mversionrc new file mode 100644 index 000000000..2d7fc1a87 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/.mversionrc @@ -0,0 +1,8 @@ +{ + "commitMessage": "Bumped version to %s", + "tagName": "%s", + "scripts": { + "preupdate": "npm run min", + "postupdate": "git push && git push --tags && npm publish" + } +} diff --git a/includes/services/Leaflet/leaflet-providers/.travis.yml b/includes/services/Leaflet/leaflet-providers/.travis.yml new file mode 100644 index 000000000..204dab530 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/.travis.yml @@ -0,0 +1,8 @@ +--- +language: node_js +node_js: + - "0.10" +notifications: + email: false +git: + depth: 10 diff --git a/includes/services/Leaflet/leaflet-providers/CHANGELOG.md b/includes/services/Leaflet/leaflet-providers/CHANGELOG.md new file mode 100644 index 000000000..c6ba59db2 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/CHANGELOG.md @@ -0,0 +1,46 @@ + +# Leaflet-providers changelog + +## 1.1.14 (2016-07-15) +- Remove MapQuest, fixes #219 +- Accidently skipped v1.1.12 and v1.1.13 + +## 1.1.11 (2016-06-04) + - Added protocol relativity to OSM FR, OSM HOT and Hydda providers (#214, #215). + +## 1.1.9 (2016-03-23) + - Re-added HERE layers #209, discussion in #206. + +## 1.1.8 (2016-03-22) + - Removed HERE layers #206 + +## 1.1.7 (2015-12-16) + - Removed Acetate tile layers #198 + +## 1.1.6 (2015-11-03) + - Removed most of the NLS layers per NLS request #193, fixes #178 + - Added new variants to the HERE provider #183 by [@andreaswc](https://github.com/andreaswc) + - Added some tests to make sure all the placeholders in the url template are replaced #188 + +## 1.1.5 (2015-10-01) + - Improvements for the NLS layers #182 by [@tomhughes](https://github.com/tomhughes) + - Check for valid bounds before fitting the preview map to undefined (fixes #185) + - Add bounds for FreeMapSK (fixes #184) + - Fix Stamen layers with `.jpg` extension (#187, fixes #184) + +## 1.1.4 (2015-09-27) + - Only include the interesting files in the npm package #180 + - Add GSGS_Ireland to NLS provider with `tms:true` to invert y-axis #181 + +## 1.1.3 (2015-09-26) + - Add various historical layers of the Natioanal library of Scotland (NLS) #179 + - Add a page to visually check bounds #179 + +## 1.1.2 (2015-09-05) + - Add CartoDB labels-only styles #170 by [@almccon](https://github.com/almccon) + - Implement commonjs module #172 + - Added retina URL option #177, [@routexl](https://github.com/routexl) + +## 1.1.1 (2015-06-22) + - Update Mapbox API to v4 #167 by [@gutenye](https://github.com/gutenye) + - Started maintaining a changelog in CHANGELOG.md. diff --git a/includes/services/Leaflet/leaflet-providers/CONTRIBUTING.md b/includes/services/Leaflet/leaflet-providers/CONTRIBUTING.md new file mode 100644 index 000000000..87766e997 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/CONTRIBUTING.md @@ -0,0 +1,10 @@ +So you want to add a layer? +======= + +Yay! go add it to the leaflet-providers.js as long as it follows the following +rules: + +- Don't violate a providers TOS (if it exists, include a link to it) +- Don't pre-populate api keys with working keys. +- It should be a basic tile source, no exteral libraries etc. +- The owner hasn't asked us to remove it (hasn't happened yet) \ No newline at end of file diff --git a/includes/services/Leaflet/leaflet-providers/README.md b/includes/services/Leaflet/leaflet-providers/README.md new file mode 100644 index 000000000..0819e15ed --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/README.md @@ -0,0 +1,63 @@ +Leaflet-providers +================= +An extension to [Leaflet](http://leafletjs.com/) that contains configurations for various free[1](#what-is-free) tile providers. + +# Usage +Leaflet-providers [providers](#providers) are refered to with a `provider[.]`-string. Let's say you want to add the nice [Watercolor](http://maps.stamen.com/#watercolor/) style from Stamen to your map, you pass `Stamen.Watercolor` to the `L.tileLayer.provider`-constructor, which will return a [L.TileLayer](http://leafletjs.com/reference.html#tilelayer) instance for Stamens Watercolor tile layer. + +```Javascript +// add Stamen Watercolor to map. +L.tileLayer.provider('Stamen.Watercolor').addTo(map); +``` + +## Protocol relativity (`https://`-urls) + +Leaflet-providers tries to use `https://` if the page uses `https://` and the provider supports it. +You can force the use of `http://` by passing `force_http: true` in the options argument. + +## Retina tiles + +Some providers have retina tiles for which the URL only needs to be slightly adjusted, e.g. `-----@2x.png`. For this, add the retina option in the URL, e.g. `-----{retina}.png`, and set a retina value in the options, e.g. `retina: '@2x'`. If Leaflet detects a retina screen (`L.Browser.retina`), the retina option passed to the tileLayer is set to the value supplied, otherwise it's replaced by an empty string. + +# Providers + +Leaflet-providers provides tile layers from different providers, including *OpenStreetMap*, *Stamen*, *Esri* and *OpenWeatherMap*. The full listing of free to use layers can be [previewed](http://leaflet-extras.github.io/leaflet-providers/preview/index.html). The page will show you the name to use with `leaflet-providers.js` and the code to use it without dependencies. + +## Providers requiring registration + +In addition to the providers you are free1 to use, we support some layers which require registration. + +### HERE (formerly Nokia). + +In order to use HERE layers, you must [register](http://developer.here.com/). Once registered, you can create an `app_id` and `app_code` which you have to pass to `L.tileLayer.provider` in the options: + +```Javascript +L.tileLayer.provider('HERE.terrainDay', { + app_id: '', + app_code: '' +}).addTo(map); +``` + +[Available HERE layers](http://leaflet-extras.github.io/leaflet-providers/preview/#filter=HERE) + +### Mapbox + +In order to use Mapbox maps, you must [register](https://tiles.mapbox.com/signup). You can get map ID and ACCESS_TOKEN from [Mapbox projects](https://www.mapbox.com/projects): +```JavaScript +L.tileLayer.provider('MapBox', {id: 'ID', accessToken: 'ACCESS_TOKEN'}).addTo(map); +``` + +### Esri/ArcGIS + +In order to use ArcGIS maps, you must [register](https://developers.arcgis.com/en/sign-up/) and abide by the [terms of service](https://developers.arcgis.com/en/terms/). No special syntax is required. + +[Available Esri layers](http://leaflet-extras.github.io/leaflet-providers/preview/#filter=Esri) + +# Attribution + +This work was inspired from , and originally created by [Stefan Seelmann](https://github.com/seelmann). + +### What do we mean by *free*? +1 +We try to maintain leaflet-providers in such a way that you'll be able to use the layers we include without paying money. +This doesn't mean no limits apply, you should always check before using these layers for anything serious. diff --git a/includes/services/Leaflet/leaflet-providers/bower.json b/includes/services/Leaflet/leaflet-providers/bower.json new file mode 100644 index 000000000..744fd4c91 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/bower.json @@ -0,0 +1,25 @@ +{ + "name": "leaflet-providers", + "version": "1.1.15", + "homepage": "https://github.com/leaflet-extras/leaflet-providers", + "description": "An extension to Leaflet that contains configurations for various free tile providers.", + "dependencies": { + "leaflet": "~0.7.3" + }, + "main": "leaflet-providers.js", + "keywords": [ + "leaflet", + "stamen", + "osm" + ], + "license": "BSD-2-Clause", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "preview", + "*.html" + ] +} diff --git a/includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.css b/includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.css new file mode 100644 index 000000000..84af6ac27 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.css @@ -0,0 +1,127 @@ +/* Left will inherit from right (so we don't need to duplicate code */ +.github-fork-ribbon { + /* The right and left lasses determine the side we attach our banner to */ + position: absolute; + + /* Add a bit of padding to give some substance outside the "stitching" */ + padding: 2px 0; + + /* Set the base colour */ + background-color: #a00; + + /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */ + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.00)), to(rgba(0, 0, 0, 0.15))); + background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); + background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); + background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); + background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); + background-image: linear-gradient(top, rgba(0, 0, 0, 0.00), rgba(0, 0, 0, 0.15)); + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000'); + + /* Add a drop shadow */ + -webkit-box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); + box-shadow: 0px 2px 3px 0px rgba(0, 0, 0, 0.5); + + z-index: 9999; +} + +.github-fork-ribbon a { + /* Set the font */ + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: 700; + color: white; + + /* Set the text properties */ + text-decoration: none; + text-shadow: 0 -1px rgba(0,0,0,0.5); + text-align: center; + + /* Set the geometry. If you fiddle with these you'll also need to tweak the top and right values in #github-fork-ribbon. */ + width: 200px; + line-height: 20px; + + /* Set the layout properties */ + display: inline-block; + padding: 2px 0; + + /* Add "stitching" effect */ + border-width: 1px 0; + border-style: dotted; + border-color: rgba(255,255,255,0.7); +} + +.github-fork-ribbon-wrapper { + width: 150px; + height: 150px; + position: absolute; + overflow: hidden; + top: 0; +} + +.github-fork-ribbon-wrapper.left { + left: 0; +} + +.github-fork-ribbon-wrapper.right { + right: 0; +} + +.github-fork-ribbon-wrapper.left-bottom { + position: fixed; + top: inherit; + bottom: 0; + left: 0; +} + +.github-fork-ribbon-wrapper.right-bottom { + position: fixed; + top: inherit; + bottom: 0; + right: 0; +} + +.github-fork-ribbon-wrapper.right .github-fork-ribbon { + top: 42px; + right: -43px; + + /* Rotate the banner 45 degrees */ + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} + +.github-fork-ribbon-wrapper.left .github-fork-ribbon { + top: 42px; + left: -43px; + + /* Rotate the banner -45 degrees */ + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -o-transform: rotate(-45deg); + transform: rotate(-45deg); +} + + +.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { + top: 80px; + left: -43px; + + /* Rotate the banner -45 degrees */ + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} + +.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { + top: 80px; + right: -43px; + + /* Rotate the banner -45 degrees */ + -webkit-transform: rotate(-45deg); + -moz-transform: rotate(-45deg); + -o-transform: rotate(-45deg); + transform: rotate(-45deg); +} \ No newline at end of file diff --git a/includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.ie.css b/includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.ie.css new file mode 100644 index 000000000..77fcab505 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/css/gh-fork-ribbon.ie.css @@ -0,0 +1,68 @@ +/* IE voodoo courtesy of http://stackoverflow.com/a/4617511/263871 and + * http://www.useragentman.com/IETransformsTranslator */ +.github-fork-ribbon-wrapper.right .github-fork-ribbon { + /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ + top: -22px; + right: -62px; + + /* IE8+ */ + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; + /* IE6 and 7 */ + filter: progid:DXImageTransform.Microsoft.Matrix( + M11=0.7071067811865474, + M12=-0.7071067811865477, + M21=0.7071067811865477, + M22=0.7071067811865474, + SizingMethod='auto expand' + ); +} + +.github-fork-ribbon-wrapper.left .github-fork-ribbon { + top: -22px; + left: -22px; + + /* IE8+ */ + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; + /* IE6 and 7 */ + filter: progid:DXImageTransform.Microsoft.Matrix( + M11=0.7071067811865483, + M12=0.7071067811865467, + M21=-0.7071067811865467, + M22=0.7071067811865483, + SizingMethod='auto expand' + ); +} + +.github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { + /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ + top: 12px; + left: -22px; + + + /* IE8+ */ + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; + /* IE6 and 7 */ +/* filter: progid:DXImageTransform.Microsoft.Matrix( + M11=0.7071067811865474, + M12=-0.7071067811865477, + M21=0.7071067811865477, + M22=0.7071067811865474, + SizingMethod='auto expand' + ); +*/} + +.github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { + top: 12px; + right: -62px; + + /* IE8+ */ + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; + /* IE6 and 7 */ + filter: progid:DXImageTransform.Microsoft.Matrix( + M11=0.7071067811865483, + M12=0.7071067811865467, + M21=-0.7071067811865467, + M22=0.7071067811865483, + SizingMethod='auto expand' + ); +} \ No newline at end of file diff --git a/includes/services/Leaflet/leaflet-providers/index.html b/includes/services/Leaflet/leaflet-providers/index.html new file mode 100644 index 000000000..df73cc780 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/index.html @@ -0,0 +1,94 @@ + + + + Leaflet Provider Demo + + + + + + + + + + + + +
+ + + + + + diff --git a/includes/services/Leaflet/leaflet-providers/leaflet-providers.js b/includes/services/Leaflet/leaflet-providers/leaflet-providers.js new file mode 100644 index 000000000..22e2cbdbd --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/leaflet-providers.js @@ -0,0 +1,639 @@ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['leaflet'], factory); + } else if (typeof modules === 'object' && module.exports) { + // define a Common JS module that relies on 'leaflet' + module.exports = factory(require('leaflet')); + } else { + // Assume Leaflet is loaded into global object L already + factory(L); + } +}(this, function (L) { + 'use strict'; + + L.TileLayer.Provider = L.TileLayer.extend({ + initialize: function (arg, options) { + var providers = L.TileLayer.Provider.providers; + + var parts = arg.split('.'); + + var providerName = parts[0]; + var variantName = parts[1]; + + if (!providers[providerName]) { + throw 'No such provider (' + providerName + ')'; + } + + var provider = { + url: providers[providerName].url, + options: providers[providerName].options + }; + + // overwrite values in provider from variant. + if (variantName && 'variants' in providers[providerName]) { + if (!(variantName in providers[providerName].variants)) { + throw 'No such variant of ' + providerName + ' (' + variantName + ')'; + } + var variant = providers[providerName].variants[variantName]; + var variantOptions; + if (typeof variant === 'string') { + variantOptions = { + variant: variant + }; + } else { + variantOptions = variant.options; + } + provider = { + url: variant.url || provider.url, + options: L.Util.extend({}, provider.options, variantOptions) + }; + } + + var forceHTTP = window.location.protocol === 'file:' || provider.options.forceHTTP; + if (provider.url.indexOf('//') === 0 && forceHTTP) { + provider.url = 'http:' + provider.url; + } + + // If retina option is set + if (provider.options.retina) { + // Check retina screen + if (options.detectRetina && L.Browser.retina) { + // The retina option will be active now + // But we need to prevent Leaflet retina mode + options.detectRetina = false; + } else { + // No retina, remove option + provider.options.retina = ''; + } + } + + // replace attribution placeholders with their values from toplevel provider attribution, + // recursively + var attributionReplacer = function (attr) { + if (attr.indexOf('{attribution.') === -1) { + return attr; + } + return attr.replace(/\{attribution.(\w*)\}/, + function (match, attributionName) { + return attributionReplacer(providers[attributionName].options.attribution); + } + ); + }; + provider.options.attribution = attributionReplacer(provider.options.attribution); + + // Compute final options combining provider options with any user overrides + var layerOpts = L.Util.extend({}, provider.options, options); + L.TileLayer.prototype.initialize.call(this, provider.url, layerOpts); + } + }); + + /** + * Definition of providers. + * see http://leafletjs.com/reference.html#tilelayer for options in the options map. + */ + + L.TileLayer.Provider.providers = { + OpenStreetMap: { + url: '//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: + '© OpenStreetMap' + }, + variants: { + Mapnik: {}, + BlackAndWhite: { + url: 'http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', + options: { + maxZoom: 18 + } + }, + DE: { + url: 'http://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png', + options: { + maxZoom: 18 + } + }, + France: { + url: '//{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', + options: { + maxZoom: 20, + attribution: '© Openstreetmap France | {attribution.OpenStreetMap}' + } + }, + HOT: { + url: '//{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', + options: { + attribution: '{attribution.OpenStreetMap}, Tiles courtesy of Humanitarian OpenStreetMap Team' + } + } + } + }, + OpenSeaMap: { + url: 'http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', + options: { + attribution: 'Map data: © OpenSeaMap contributors' + } + }, + OpenTopoMap: { + url: '//{s}.tile.opentopomap.org/{z}/{x}/{y}.png', + options: { + maxZoom: 17, + attribution: 'Map data: {attribution.OpenStreetMap}, SRTM | Map style: © OpenTopoMap (CC-BY-SA)' + } + }, + Thunderforest: { + url: '//{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png', + options: { + attribution: + '© Thunderforest, {attribution.OpenStreetMap}', + variant: 'cycle' + }, + variants: { + OpenCycleMap: 'cycle', + Transport: { + options: { + variant: 'transport', + maxZoom: 19 + } + }, + TransportDark: { + options: { + variant: 'transport-dark', + maxZoom: 19 + } + }, + SpinalMap: { + options: { + variant: 'spinal-map', + maxZoom: 11 + } + }, + Landscape: 'landscape', + Outdoors: 'outdoors', + Pioneer: 'pioneer' + } + }, + OpenMapSurfer: { + url: 'http://korona.geog.uni-heidelberg.de/tiles/{variant}/x={x}&y={y}&z={z}', + options: { + maxZoom: 20, + variant: 'roads', + attribution: 'Imagery from GIScience Research Group @ University of Heidelberg — Map data {attribution.OpenStreetMap}' + }, + variants: { + Roads: 'roads', + AdminBounds: { + options: { + variant: 'adminb', + maxZoom: 19 + } + }, + Grayscale: { + options: { + variant: 'roadsg', + maxZoom: 19 + } + } + } + }, + Hydda: { + url: '//{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png', + options: { + variant: 'full', + attribution: 'Tiles courtesy of OpenStreetMap Sweden — Map data {attribution.OpenStreetMap}' + }, + variants: { + Full: 'full', + Base: 'base', + RoadsAndLabels: 'roads_and_labels' + } + }, + MapBox: { + url: '//api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', + options: { + attribution: + 'Imagery from MapBox — ' + + 'Map data {attribution.OpenStreetMap}', + subdomains: 'abcd' + } + }, + Stamen: { + url: '//stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}', + options: { + attribution: + 'Map tiles by Stamen Design, ' + + 'CC BY 3.0 — ' + + 'Map data {attribution.OpenStreetMap}', + subdomains: 'abcd', + minZoom: 0, + maxZoom: 20, + variant: 'toner', + ext: 'png' + }, + variants: { + Toner: 'toner', + TonerBackground: 'toner-background', + TonerHybrid: 'toner-hybrid', + TonerLines: 'toner-lines', + TonerLabels: 'toner-labels', + TonerLite: 'toner-lite', + Watercolor: { + options: { + variant: 'watercolor', + minZoom: 1, + maxZoom: 16 + } + }, + Terrain: { + options: { + variant: 'terrain', + minZoom: 0, + maxZoom: 18 + } + }, + TerrainBackground: { + options: { + variant: 'terrain-background', + minZoom: 0, + maxZoom: 18 + } + }, + TopOSMRelief: { + options: { + variant: 'toposm-color-relief', + ext: 'jpg', + bounds: [[22, -132], [51, -56]] + } + }, + TopOSMFeatures: { + options: { + variant: 'toposm-features', + bounds: [[22, -132], [51, -56]], + opacity: 0.9 + } + } + } + }, + Esri: { + url: '//server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}', + options: { + variant: 'World_Street_Map', + attribution: 'Tiles © Esri' + }, + variants: { + WorldStreetMap: { + options: { + attribution: + '{attribution.Esri} — ' + + 'Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012' + } + }, + DeLorme: { + options: { + variant: 'Specialty/DeLorme_World_Base_Map', + minZoom: 1, + maxZoom: 11, + attribution: '{attribution.Esri} — Copyright: ©2012 DeLorme' + } + }, + WorldTopoMap: { + options: { + variant: 'World_Topo_Map', + attribution: + '{attribution.Esri} — ' + + 'Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community' + } + }, + WorldImagery: { + options: { + variant: 'World_Imagery', + attribution: + '{attribution.Esri} — ' + + 'Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community' + } + }, + WorldTerrain: { + options: { + variant: 'World_Terrain_Base', + maxZoom: 13, + attribution: + '{attribution.Esri} — ' + + 'Source: USGS, Esri, TANA, DeLorme, and NPS' + } + }, + WorldShadedRelief: { + options: { + variant: 'World_Shaded_Relief', + maxZoom: 13, + attribution: '{attribution.Esri} — Source: Esri' + } + }, + WorldPhysical: { + options: { + variant: 'World_Physical_Map', + maxZoom: 8, + attribution: '{attribution.Esri} — Source: US National Park Service' + } + }, + OceanBasemap: { + options: { + variant: 'Ocean_Basemap', + maxZoom: 13, + attribution: '{attribution.Esri} — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri' + } + }, + NatGeoWorldMap: { + options: { + variant: 'NatGeo_World_Map', + maxZoom: 16, + attribution: '{attribution.Esri} — National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC' + } + }, + WorldGrayCanvas: { + options: { + variant: 'Canvas/World_Light_Gray_Base', + maxZoom: 16, + attribution: '{attribution.Esri} — Esri, DeLorme, NAVTEQ' + } + } + } + }, + OpenWeatherMap: { + url: 'http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: 'Map data © OpenWeatherMap', + opacity: 0.5 + }, + variants: { + Clouds: 'clouds', + CloudsClassic: 'clouds_cls', + Precipitation: 'precipitation', + PrecipitationClassic: 'precipitation_cls', + Rain: 'rain', + RainClassic: 'rain_cls', + Pressure: 'pressure', + PressureContour: 'pressure_cntr', + Wind: 'wind', + Temperature: 'temp', + Snow: 'snow' + } + }, + HERE: { + /* + * HERE maps, formerly Nokia maps. + * These basemaps are free, but you need an API key. Please sign up at + * http://developer.here.com/getting-started + * + * Note that the base urls contain '.cit' whichs is HERE's + * 'Customer Integration Testing' environment. Please remove for production + * envirionments. + */ + url: + '//{s}.{base}.maps.cit.api.here.com/maptile/2.1/' + + '{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?' + + 'app_id={app_id}&app_code={app_code}&lg={language}', + options: { + attribution: + 'Map © 1987-2014 HERE', + subdomains: '1234', + mapID: 'newest', + 'app_id': '', + 'app_code': '', + base: 'base', + variant: 'normal.day', + maxZoom: 20, + type: 'maptile', + language: 'eng', + format: 'png8', + size: '256' + }, + variants: { + normalDay: 'normal.day', + normalDayCustom: 'normal.day.custom', + normalDayGrey: 'normal.day.grey', + normalDayMobile: 'normal.day.mobile', + normalDayGreyMobile: 'normal.day.grey.mobile', + normalDayTransit: 'normal.day.transit', + normalDayTransitMobile: 'normal.day.transit.mobile', + normalNight: 'normal.night', + normalNightMobile: 'normal.night.mobile', + normalNightGrey: 'normal.night.grey', + normalNightGreyMobile: 'normal.night.grey.mobile', + + basicMap: { + options: { + type: 'basetile' + } + }, + mapLabels: { + options: { + type: 'labeltile', + format: 'png' + } + }, + trafficFlow: { + options: { + base: 'traffic', + type: 'flowtile' + } + }, + carnavDayGrey: 'carnav.day.grey', + hybridDay: { + options: { + base: 'aerial', + variant: 'hybrid.day' + } + }, + hybridDayMobile: { + options: { + base: 'aerial', + variant: 'hybrid.day.mobile' + } + }, + pedestrianDay: 'pedestrian.day', + pedestrianNight: 'pedestrian.night', + satelliteDay: { + options: { + base: 'aerial', + variant: 'satellite.day' + } + }, + terrainDay: { + options: { + base: 'aerial', + variant: 'terrain.day' + } + }, + terrainDayMobile: { + options: { + base: 'aerial', + variant: 'terrain.day.mobile' + } + } + } + }, + FreeMapSK: { + url: 'http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg', + options: { + minZoom: 8, + maxZoom: 16, + subdomains: '1234', + bounds: [[47.204642, 15.996093], [49.830896, 22.576904]], + attribution: + '{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 Freemap.sk' + } + }, + MtbMap: { + url: 'http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png', + options: { + attribution: + '{attribution.OpenStreetMap} & USGS' + } + }, + CartoDB: { + url: 'http://{s}.basemaps.cartocdn.com/{variant}/{z}/{x}/{y}.png', + options: { + attribution: '{attribution.OpenStreetMap} © CartoDB', + subdomains: 'abcd', + maxZoom: 19, + variant: 'light_all' + }, + variants: { + Positron: 'light_all', + PositronNoLabels: 'light_nolabels', + PositronOnlyLabels: 'light_only_labels', + DarkMatter: 'dark_all', + DarkMatterNoLabels: 'dark_nolabels', + DarkMatterOnlyLabels: 'dark_only_labels' + } + }, + HikeBike: { + url: 'http://{s}.tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png', + options: { + maxZoom: 19, + attribution: '{attribution.OpenStreetMap}', + variant: 'hikebike' + }, + variants: { + HikeBike: {}, + HillShading: { + options: { + maxZoom: 15, + variant: 'hillshading' + } + } + } + }, + BasemapAT: { + url: '//maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}', + options: { + maxZoom: 19, + attribution: 'Datenquelle: basemap.at', + subdomains: ['', '1', '2', '3', '4'], + format: 'png', + bounds: [[46.358770, 8.782379], [49.037872, 17.189532]], + variant: 'geolandbasemap' + }, + variants: { + basemap: 'geolandbasemap', + grau: 'bmapgrau', + overlay: 'bmapoverlay', + highdpi: { + options: { + variant: 'bmaphidpi', + format: 'jpeg' + } + }, + orthofoto: { + options: { + variant: 'bmaporthofoto30cm', + format: 'jpeg' + } + } + } + }, + NASAGIBS: { + url: '//map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}', + options: { + attribution: + 'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System ' + + '(ESDIS) with funding provided by NASA/HQ.', + bounds: [[-85.0511287776, -179.999999975], [85.0511287776, 179.999999975]], + minZoom: 1, + maxZoom: 9, + format: 'jpg', + time: '', + tilematrixset: 'GoogleMapsCompatible_Level' + }, + variants: { + ModisTerraTrueColorCR: 'MODIS_Terra_CorrectedReflectance_TrueColor', + ModisTerraBands367CR: 'MODIS_Terra_CorrectedReflectance_Bands367', + ViirsEarthAtNight2012: { + options: { + variant: 'VIIRS_CityLights_2012', + maxZoom: 8 + } + }, + ModisTerraLSTDay: { + options: { + variant: 'MODIS_Terra_Land_Surface_Temp_Day', + format: 'png', + maxZoom: 7, + opacity: 0.75 + } + }, + ModisTerraSnowCover: { + options: { + variant: 'MODIS_Terra_Snow_Cover', + format: 'png', + maxZoom: 8, + opacity: 0.75 + } + }, + ModisTerraAOD: { + options: { + variant: 'MODIS_Terra_Aerosol', + format: 'png', + maxZoom: 6, + opacity: 0.75 + } + }, + ModisTerraChlorophyll: { + options: { + variant: 'MODIS_Terra_Chlorophyll_A', + format: 'png', + maxZoom: 7, + opacity: 0.75 + } + } + } + }, + NLS: { + // NLS maps are copyright National library of Scotland. + // http://maps.nls.uk/projects/api/index.html + // Please contact NLS for anything other than non-commercial low volume usage + // + // Map sources: Ordnance Survey 1:1m to 1:63K, 1920s-1940s + // z0-9 - 1:1m + // z10-11 - quarter inch (1:253440) + // z12-18 - one inch (1:63360) + url: '//nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', + options: { + attribution: 'National Library of Scotland Historic Maps', + bounds: [[49.6, -12], [61.7, 3]], + minZoom: 1, + maxZoom: 18, + subdomains: '0123', + } + } + }; + + L.tileLayer.provider = function (provider, options) { + return new L.TileLayer.Provider(provider, options); + }; + + return L; +})); diff --git a/includes/services/Leaflet/leaflet-providers/license.md b/includes/services/Leaflet/leaflet-providers/license.md new file mode 100644 index 000000000..4c48832e5 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/license.md @@ -0,0 +1,9 @@ +Copyright (c) 2013 Leaflet Providers contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +_THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE._ \ No newline at end of file diff --git a/includes/services/Leaflet/leaflet-providers/package.json b/includes/services/Leaflet/leaflet-providers/package.json new file mode 100644 index 000000000..f4cbdc36d --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/package.json @@ -0,0 +1,45 @@ +{ + "name": "leaflet-providers", + "version": "1.1.15", + "description": "An extension to Leaflet that contains configurations for various free tile providers.", + "main": "leaflet-providers.js", + "repository": { + "type": "git", + "url": "git://github.com/leaflet-extras/leaflet-providers.git" + }, + "scripts": { + "test": "npm run lint && npm run testsuite", + "testsuite": "mocha-phantomjs tests/index.html", + "lint": "eslint --config .eslintrc leaflet-providers.js index.html preview/*.js preview/*.html tests/*", + "min": "uglifyjs leaflet-providers.js -mc -o leaflet-providers.min.js", + "release": "mversion patch -m" + }, + "license": "BSD-2-Clause", + "bugs": { + "url": "https://github.com/leaflet-extras/leaflet-providers/issues" + }, + "files": [ + "leaflet-providers.js", + "README.md", + "CHANGELOG.md", + "licence.md" + ], + "devDependencies": { + "chai": "^2.3.0", + "eslint": "^2.7.0", + "eslint-plugin-html": "^1.4.0", + "mocha": "^2.2.4", + "mocha-phantomjs": "^3.5.3", + "mversion": "^1.3.0", + "phantomjs": "1.9.7-15", + "uglify-js": "^2.4.15" + }, + "autoupdate": { + "source": "git", + "target": "git://github.com/leaflet-extras/leaflet-providers.git", + "basePath": "/", + "files": [ + "leaflet-providers.js" + ] + } +} diff --git a/includes/services/Leaflet/leaflet-providers/preview/https-support.js b/includes/services/Leaflet/leaflet-providers/preview/https-support.js new file mode 100644 index 000000000..de079787a --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/https-support.js @@ -0,0 +1,57 @@ +L.TileLayer.prototype._tileOnError = function () { + if (this.errorContainer) { + this.errorContainer.innerHTML = 'seems to be not supported'; + } +} + + +var container = L.DomUtil.get('maps'); + +function addLayer (provider) { + var layer = L.tileLayer.provider(provider); + + var httpsSupported = layer._url.indexOf('//') === 0; + var table = L.DomUtil.get('table-' + (httpsSupported ? 'supported' : 'unknown')); + + var url = layer._url.replace('{variant}', layer.options.variant); + var options = L.extend({}, layer.options, layer._options); + + if (url.indexOf('http:') === 0) { + url = url.slice(5); + } else if (url.indexOf('https:') === 0) { + url = url.slice(6); + } + + var row = L.DomUtil.create('tr', '', table); + L.DomUtil.create('td', '', row).innerHTML = provider; + var result = L.DomUtil.create('td', '', row); + L.DomUtil.create('button', '', result).innerHTML = 'test...'; + if (httpsSupported) { + result.innerHTML = ' ' + result.innerHTML; + } + + L.DomEvent.on(result, 'click', function () { + var center = [52, 4]; + if ('bounds' in options && options.bounds) { + center = L.latLngBounds(options.bounds).getCenter(); + } + result.innerHTML = 'testing...'; + container.innerHTML = ''; + L.DomUtil.create('h2', '', container).innerHTML = provider + ' (http):'; + + var map1 = L.map(L.DomUtil.create('div', 'map', container)).setView(center, 9); + map1.addLayer(L.tileLayer('http:' + url, options)); + + L.DomUtil.create('h2', '', container).innerHTML = provider + ' (https):'; + var map2 = L.map(L.DomUtil.create('div', 'map', container)).setView(center, 9); + + var httpsLayer = L.tileLayer('https:' + url, options).addTo(map2); + + httpsLayer.errorContainer = result; + httpsLayer.on('load', function () { + result.innerHTML = 'seems to be OK'; + }); + }); +} + +L.tileLayer.provider.eachLayer(addLayer); diff --git a/includes/services/Leaflet/leaflet-providers/preview/index.html b/includes/services/Leaflet/leaflet-providers/preview/index.html new file mode 100644 index 000000000..f6645b854 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/index.html @@ -0,0 +1,90 @@ + + + + Leaflet Provider Demo + + + + + + + + + + + + + + + + +
+

Leaflet-providers preview

+

+ This page shows mini maps for all the layers available in Leaflet-providers. +

+
+
+ + + + + + + + + + + + diff --git a/includes/services/Leaflet/leaflet-providers/preview/layer-bounds.js b/includes/services/Leaflet/leaflet-providers/preview/layer-bounds.js new file mode 100644 index 000000000..14b415bc2 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/layer-bounds.js @@ -0,0 +1,63 @@ +var table = L.DomUtil.get('table'); +var container = L.DomUtil.get('maps'); +var result = L.DomUtil.get('result'); + +var map, rect; + +function showBounds () { + if (!(map && result)) { + return; + } + var b = rect.getBounds() + result.innerHTML = '

Bounds for this layer:

' + + '\n\n[' + + '[' + b.getSouth() + ', ' + b.getWest() + '], ' + + '[' + b.getNorth() + ', ' + b.getEast() + ']' + + ']

' + + 'zoomlevel: ' + map.getZoom(); +} + +function addLayer (provider) { + var layer = L.tileLayer.provider(provider); + + // we're only interested in layers with bounds here. + if (!layer.options.bounds) { + return; + } + var bounds = L.latLngBounds(layer.options.bounds); + + var row = L.DomUtil.create('tr', '', table); + L.DomUtil.create('td', '', row).innerHTML = provider; + + L.DomEvent.on(row, 'click', function () { + if (map && map.remove) { + map.remove(); + } + for (var i = 0; i < table.children.length; i++) { + L.DomUtil.removeClass(table.children[i], 'active'); + } + L.DomUtil.addClass(row, 'active'); + + container.innerHTML = ''; + L.DomUtil.create('h2', '', container).innerHTML = provider; + + map = L.map(L.DomUtil.create('div', 'map', container)).setView([52, 4], 6); + map.addLayer(L.tileLayer.provider('Hydda.Base')); + map.addLayer(layer); + + rect = L.rectangle(bounds, { + fill: false, + weight: 2, + opacity: 1 + }).addTo(map); + + rect.editing.enable(); + map.on('click zoomend', showBounds); + showBounds(); + + map.fitBounds(bounds); + }); +} +L.DomEvent.on(L.DomUtil.get('dump-bounds'), 'click', showBounds); + +L.tileLayer.provider.eachLayer(addLayer); diff --git a/includes/services/Leaflet/leaflet-providers/preview/preview.js b/includes/services/Leaflet/leaflet-providers/preview/preview.js new file mode 100644 index 000000000..9e8c85da4 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/preview.js @@ -0,0 +1,227 @@ +(function () { + 'use strict'; + + var map = new L.Map('map', { + zoomControl: false, + center: [48, -3], + zoom: 5 + }); + + function escapeHtml (string) { + return string + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + function renderValue (value) { + if (typeof value === 'string') { + return "'" + escapeHtml(value) + "'"; + } else { + return JSON.stringify(value).replace(/,/g, ', '); + } + } + + L.TileLayer.include({ + getExampleJS: function () { + var layerName = this._providerName.replace('.', '_'); + + var url = this._exampleUrl || this._url; + var options = L.extend({}, this._options, this._exampleAPIcodes || {}); + + // replace {variant} in urls with the selected variant, since + // keeping it in the options map doesn't make sense for one layer + if (options.variant) { + url = url.replace('{variant}', options.variant); + delete options.variant; + } + + var code = ''; + if (url.indexOf('//') === 0) { + code += '// https: also suppported.\n'; + url = 'http:' + url; + } + code += 'var ' + layerName + ' = L.tileLayer(\'' + url + '\', {\n'; + + var first = true; + for (var option in options) { + if (first) { + first = false; + } else { + code += ',\n'; + } + code += '\t' + option + ': ' + renderValue(options[option]); + } + code += '\n});\n'; + + return code; + } + }); + + var isOverlay = function (providerName, layer) { + if (layer.options.opacity && layer.options.opacity < 1) { + return true; + } + var overlayPatterns = [ + '^(OpenWeatherMap|OpenSeaMap)', + 'OpenMapSurfer.AdminBounds', + 'Stamen.Toner(Hybrid|Lines|Labels)', + 'Acetate.(foreground|labels|roads)', + 'Hydda.RoadsAndLabels' + ]; + + return providerName.match('(' + overlayPatterns.join('|') + ')') !== null; + }; + + // Ignore some providers in the preview + var isIgnored = function (providerName) { + if (providerName === 'ignored') { + return true; + } + // reduce the number of layers previewed for some providers + if (providerName.startsWith('HERE') || providerName.startsWith('OpenWeatherMap')) { + var whitelist = [ + 'HERE.normalDay', + 'HERE.basicMap', + 'HERE.hybridDay', + 'OpenWeatherMap.Clouds', + 'OpenWeatherMap.Pressure', + 'OpenWeatherMap.Wind' + ]; + return whitelist.indexOf(providerName) === -1; + } + return false; + }; + + // collect all layers available in the provider definition + var baseLayers = {}; + var overlays = {}; + + var addLayer = function (name) { + if (isIgnored(name)) { + return; + } + var layer = L.tileLayer.provider(name); + if (isOverlay(name, layer)) { + overlays[name] = layer; + } else { + baseLayers[name] = layer; + } + }; + L.tileLayer.provider.eachLayer(addLayer); + + // add minimap control to the map + var layersControl = L.control.layers.minimap(baseLayers, overlays, { + collapsed: false + }).addTo(map); + + // Pass a filter in the hash tag to show only layers containing that string + // for example: #filter=Open + var filterLayersControl = function () { + var hash = window.location.hash; + var filterIndex = hash.indexOf('filter='); + if (filterIndex !== -1) { + var filterString = hash.substr(filterIndex + 7).trim(); + var visible = layersControl.filter(filterString); + + // enable first layer as actual layer. + var first = Object.keys(visible)[0]; + if (first in baseLayers) { + map.addLayer(baseLayers[first]); + map.eachLayer(function (layer) { + if (layer._providerName !== first) { + map.removeLayer(layer); + } + }); + layersControl.filter(filterString); + } + } + }; + L.DomEvent.on(window, 'hashchange', filterLayersControl); + + // Does not work if called immediately, so ugly hack to apply filter + // at first page load + setTimeout(filterLayersControl, 100); + + // add OpenStreetMap.Mapnik, or the first if it does not exist + if (baseLayers['OpenStreetMap.Mapnik']) { + baseLayers['OpenStreetMap.Mapnik'].addTo(map); + } else { + baseLayers[Object.keys(baseLayers)[0]].addTo(map); + } + + // if a layer is selected and if it has bounds an the bounds are not in the + // current view, move the map view to contain the bounds + map.on('baselayerchange', function (e) { + var layer = e.layer; + if (!map.hasLayer(layer)) { + return; + } + if (layer.options.minZoom > 1 && map.getZoom() > layer.options.minZoom) { + map.setZoom(layer.options.minZoom); + } + if (!layer.options.bounds) { + return; + } + var bounds = L.latLngBounds(layer.options.bounds); + map.fitBounds(bounds, { + paddingTopLeft: [0, 200], + paddingBottomRight: [200, 0] + }); + }); + + // Add the TileLayer source code control to the map + map.addControl(new (L.Control.extend({ + options: { + position: 'topleft' + }, + onAdd: function (map) { + var container = L.DomUtil.get('info'); + L.DomEvent.disableClickPropagation(container); + + L.DomUtil.create('h4', null, container).innerHTML = 'Provider names for leaflet-providers.js'; + var providerNames = L.DomUtil.create('code', 'provider-names', container); + + L.DomUtil.create('h4', '', container).innerHTML = 'Plain JavaScript:'; + var pre = L.DomUtil.create('pre', null, container); + var code = L.DomUtil.create('code', 'javascript', pre); + + var update = function (event) { + code.innerHTML = ''; + + var names = []; + + // loop over the layers in the map and add the JS + for (var key in map._layers) { + var layer = map._layers[key]; + if (!layer.getExampleJS) { + continue; + } + + // do not add the layer currently being removed + if (event && event.type === 'layerremove' && layer === event.layer) { + continue; + } + names.push(L.Util.template('{name}', { + name: layer._providerName + })); + code.innerHTML += layer.getExampleJS(); + } + providerNames.innerHTML = names.join(', '); + + /* global hljs:true */ + hljs.highlightBlock(code); + }; + + map.on({ + 'layeradd': update, + 'layerremove': update + }); + update(); + + return container; + } + }))()); +})(); diff --git a/includes/services/Leaflet/leaflet-providers/preview/shared.js b/includes/services/Leaflet/leaflet-providers/preview/shared.js new file mode 100644 index 000000000..4d4162652 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/shared.js @@ -0,0 +1,63 @@ +// This is a list of example API codes, to make this preview +// functioning. Please register with the providers to use them +// with your own app. +var exampleAPIcodes = { + 'HERE': { + 'app_id': 'oenPwMCqbQkUSqj1WhRx', + 'app_code': 'kBxLcdTofTHUlsT7tl2X5w' + }, + 'MapBox': { + 'id': 'mapbox.streets', + 'accessToken': 'pk.eyJ1IjoiZ3V0ZW55ZSIsImEiOiJmNjJlMDNmYTUyMzNjMzQxZmY4Mzc1ZmFiYmExNjMxOSJ9.xgl1PBwQV9CtwW-usedrcQ' + } +}; + +var origProviderInit = L.TileLayer.Provider.prototype.initialize; +L.TileLayer.Provider.include({ + initialize: function (providerName, options) { + this._providerName = providerName; + options = options || {}; + + // replace example API codes in options + var provider = this._providerName.split('.')[0]; + if (provider in exampleAPIcodes) { + + // overwrite exampleAPIcodes with a placeholder to prevent accidental use + // of these API codes. + this._exampleAPIcodes = {}; + for (var key in exampleAPIcodes[provider]) { + this._exampleAPIcodes[key] = ''; + } + L.extend(options, exampleAPIcodes[provider]); + } + origProviderInit.call(this, providerName, options); + } +}); + +// save the options while creating tilelayers to cleanly access them later. +var origTileLayerInit = L.TileLayer.prototype.initialize; +L.TileLayer.include({ + initialize: function (url, options) { + this._options = options; + origTileLayerInit.apply(this, arguments); + } +}); + +L.tileLayer.provider.eachLayer = function (callback) { + for (var provider in L.TileLayer.Provider.providers) { + if (L.TileLayer.Provider.providers[provider].variants) { + for (var variant in L.TileLayer.Provider.providers[provider].variants) { + callback(provider + '.' + variant); + } + } else { + callback(provider); + } + } +}; + +if (!String.prototype.startsWith) { + String.prototype.startsWith = function (searchString, position) { + position = position || 0; + return this.substr(position, searchString.length) === searchString; + }; +} diff --git a/includes/services/Leaflet/leaflet-providers/preview/test-bounds.html b/includes/services/Leaflet/leaflet-providers/preview/test-bounds.html new file mode 100644 index 000000000..50aa246e4 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/test-bounds.html @@ -0,0 +1,87 @@ + + + + Leaflet Provider - layer bounds check page + + + + + + + + + + + + + + + + +
+ + + + + + + + + diff --git a/includes/services/Leaflet/leaflet-providers/preview/test-https-support.html b/includes/services/Leaflet/leaflet-providers/preview/test-https-support.html new file mode 100644 index 000000000..7e7b0bff8 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/preview/test-https-support.html @@ -0,0 +1,79 @@ + + + + Leaflet Provider - HTTPS support check page + + + + + + + + + + + + + + +

Testing provider protocols

+
+

Known https support:

+ + +
ProviderHTTPS
+
+ +
+

Unknown https support:

+ + +
ProviderHTTPS
+
+
+ + + + + + + + diff --git a/includes/services/Leaflet/leaflet-providers/tests/index.html b/includes/services/Leaflet/leaflet-providers/tests/index.html new file mode 100644 index 000000000..cfa30c13c --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/tests/index.html @@ -0,0 +1,44 @@ + + + + leaflet-poviders Mocha Tests + + + + + + + +
+
+ + + + + + + + + + + + + + + diff --git a/includes/services/Leaflet/leaflet-providers/tests/test.js b/includes/services/Leaflet/leaflet-providers/tests/test.js new file mode 100644 index 000000000..28ef6e981 --- /dev/null +++ b/includes/services/Leaflet/leaflet-providers/tests/test.js @@ -0,0 +1,99 @@ +/* global describe, chai, it */ + +function isEmpty (obj) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + return false; + } + } + + return true; +} + +// List of valid L.TileLayer options to check options against +var validTileLayerOptions = [ + 'minZoom', 'maxZoom', 'maxNativeZoom', 'tileSize', 'subdomains', 'errorTileUrl', + 'attribution', 'tms', 'continuousWorld', 'noWrap', 'zoomOffset', 'zoomReverse', + 'opacity', 'zIndex', 'unloadInvisibleTiles', 'updateWhenIdle', 'detectRetina', + 'reuseTiles', 'bounds', 'crossOrigin', 'updateInterval', 'pane', 'nonBubblingEvents' +]; + +// monkey-patch getTileUrl with fake values. +L.TileLayer.prototype.getTileUrl = function (coords) { + return L.Util.template(this._url, L.extend({ + r: '', + s: this._getSubdomain(coords), + x: coords.x, + y: coords.y, + z: 15 + }, this.options)); +}; + +describe('leaflet-providers', function () { + chai.should(); + var providers = L.TileLayer.Provider.providers; + + describe('variant definition structure', function () { + it('each provider has keys url, options, variants', function () { + for (var name in providers) { + providers[name].should.contain.any.keys('url', 'options', 'variants'); + } + }); + it('each variant should be an object or a string', function () { + for (var name in providers) { + var variants = providers[name].variants; + + for (var v in variants) { + if (typeof variants[v] === 'string' || isEmpty(variants[v])) { + // string or empty object, which is fine. + continue; + } else { + variants[v].should.be.an.instanceof(Object); + variants[v].should.contain.any.keys('url', 'options'); + } + } + } + }); + }); + + describe('Nonexistant providers', function () { + it('should fail for non-existant providers', function () { + var fn = function () { + L.tileLayer.provider('Example'); + }; + fn.should.throw('No such provider (Example)'); + }); + it('should fail for non-existant variants of existing providers', function () { + var fn = function () { + L.tileLayer.provider('OpenStreetMap.Example'); + }; + fn.should.throw('No such variant of OpenStreetMap (Example)'); + }); + }); + + describe('Each layer', function () { + L.tileLayer.provider.eachLayer(function (name) { + describe(name, function () { + var layer = L.tileLayer.provider(name); + + it('should be a L.TileLayer', function () { + layer.should.be.an.instanceof(L.TileLayer); + }); + + it('should not throw while requesting a tile url', function () { + layer.getTileUrl({x: 16369, y: 10896}); + }); + + it('should have valid options', function () { + for (var key in layer.options) { + if (validTileLayerOptions.indexOf(key) !== -1) { + continue; + } + var placeholder = '{' + key + '}'; + layer._url.should.contain(placeholder); + } + }) + }); + }); + }) +}); From 70c20c03cd5e18f16532c29b9016573538a0a555 Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Fri, 19 Aug 2016 13:18:01 +0200 Subject: [PATCH 02/10] fix loading of dependencies --- includes/services/Leaflet/Maps_Leaflet.php | 13 +++++++++++++ includes/services/Leaflet/jquery.leaflet.js | 20 ++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/includes/services/Leaflet/Maps_Leaflet.php b/includes/services/Leaflet/Maps_Leaflet.php index be2e0018a..6186f6ce7 100644 --- a/includes/services/Leaflet/Maps_Leaflet.php +++ b/includes/services/Leaflet/Maps_Leaflet.php @@ -145,4 +145,17 @@ protected function getDependencies() { ]; } + /** + * Adds the layer dependencies. + * + * @since 3.8 + * + * @param array $dependencies + */ + public function addLayerDependencies( array $dependencies ) { + foreach ( $dependencies as $dependency ) { + $this->addDependency( $dependency ); + } + } + } diff --git a/includes/services/Leaflet/jquery.leaflet.js b/includes/services/Leaflet/jquery.leaflet.js index 496f0e749..37153a7dd 100644 --- a/includes/services/Leaflet/jquery.leaflet.js +++ b/includes/services/Leaflet/jquery.leaflet.js @@ -6,7 +6,7 @@ * @author Peter Grassberger < petertheone@gmail.com > */ -(function ($, mw, L) { +(function ($, mw, L, MQ) { $.fn.leafletmaps = function ( options ) { var _this = this; this.map = null; @@ -255,14 +255,15 @@ var layerOptions = { attribution: '© OpenStreetMap contributors' }; - if (options.layer !== 'MapQuestOpen') { - L.tileLayer.provider(options.layer, layerOptions).addTo(map); + if (options.layer === 'OpenStreetMap') { + new L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', layerOptions).addTo(map); + } else if (options.layer === 'MapQuestOpen') { + new MQ.TileLayer(layerOptions).addTo(map); } else { - //MQ.TileLayer(layerOptions).addTo(map) + new L.tileLayer.provider(options.layer, layerOptions).addTo(map); } $.each(options.overlaylayers, function(index, overlaylayer) { - console.log(overlaylayer); L.tileLayer.provider(overlaylayer).addTo(_this.map); }); @@ -344,7 +345,9 @@ this.getDependencies = function ( options ) { var dependencies = []; - dependencies.push( 'ext.maps.leaflet.providers' ); + if (options.layer !== 'OpenStreetMap' || options.overlaylayers.length > 0) { + dependencies.push( 'ext.maps.leaflet.providers' ); + } if (options.enablefullscreen) { dependencies.push( 'ext.maps.leaflet.fullscreen' ); } @@ -354,9 +357,6 @@ if (options.markercluster) { dependencies.push( 'ext.maps.leaflet.markercluster' ); } - /*if (options.layer === 'MapQuestOpen') { - // todo: load dependency - }*/ return dependencies; }; @@ -367,4 +367,4 @@ return this; }; -})(jQuery, window.mediaWiki, L); +})(jQuery, window.mediaWiki, L, MQ); From 2c4c2cfa35d9981fdc7ae1b89b190bb244c671ba Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Thu, 25 Aug 2016 17:20:51 +0200 Subject: [PATCH 03/10] add missing i18n --- i18n/en.json | 1 + i18n/qqq.json | 1 + includes/services/Leaflet/Maps_Leaflet.php | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/i18n/en.json b/i18n/en.json index ee9dc748d..c1c58c982 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -120,6 +120,7 @@ "maps_leaflet": "Leaflet", "maps-leaflet-par-defzoom": "Allows setting the default zoom level of the map.", "maps-leaflet-par-layer": "The layer that will be shown when the map loads.", + "maps-leaflet-par-overlaylayers": "The overlay layers that will be shown when the map loads.", "maps-leaflet-par-maxclusterradius": "The maximum radius that a cluster will cover from the central marker (in pixels).", "maps-leaflet-par-clusterspiderfy": "When you click a cluster at the bottom zoom level we spiderfy it so you can see all of its markers.", "maps_openlayers": "OpenLayers", diff --git a/i18n/qqq.json b/i18n/qqq.json index e6e795584..6aa0cba92 100644 --- a/i18n/qqq.json +++ b/i18n/qqq.json @@ -130,6 +130,7 @@ "maps_leaflet": "This is a field label.\n\n{{optional}}", "maps-leaflet-par-defzoom": "{{maps-par|leaflet|defzoom}}", "maps-leaflet-par-layer": "{{maps-par|leaflet|layer}}", + "maps-leaflet-par-overlaylayers": "{{maps-par|leaflet|overlaylayers}}", "maps-leaflet-par-maxclusterradius": "{{maps-par|leaflet|maxclusterradius}}", "maps-leaflet-par-clusterspiderfy": "{{maps-par|leaflet|clusterspiderfy}}", "maps_openlayers": "Lable for a result format on SMW's special page \"Ask\".\n\n{{optional}}", diff --git a/includes/services/Leaflet/Maps_Leaflet.php b/includes/services/Leaflet/Maps_Leaflet.php index 6186f6ce7..fcafcdd60 100644 --- a/includes/services/Leaflet/Maps_Leaflet.php +++ b/includes/services/Leaflet/Maps_Leaflet.php @@ -52,7 +52,7 @@ public function addParameterInfo( array &$params ) { 'type' => 'string', 'values' => $GLOBALS['egMapsLeafletAvailableOverlayLayers'], 'default' => $GLOBALS['egMapsLeafletOverlayLayers'], - 'message' =>'maps-leaflet-par-overlaylayers', // todo: add to i18n + 'message' =>'maps-leaflet-par-overlaylayers', 'islist' => true, ]; From a1c5564efd027f3f35df951469c320b793741561 Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Thu, 25 Aug 2016 17:21:57 +0200 Subject: [PATCH 04/10] disable mapbox support because of missing api key integration --- Maps_Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Maps_Settings.php b/Maps_Settings.php index a3daa7f52..9e54375ce 100644 --- a/Maps_Settings.php +++ b/Maps_Settings.php @@ -319,7 +319,7 @@ 'Thunderforest.Transport', 'Thunderforest.Landscape', 'Hydda.Full', - 'MapBox', + //'MapBox', 'Stamen.Toner', 'Stamen.Terrain', 'Stamen.Watercolor', From df0997cd5b36428530c156a955cfe29d9017797a Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Thu, 25 Aug 2016 17:30:47 +0200 Subject: [PATCH 05/10] fix LayerApiKeys settings --- Maps_Settings.php | 5 ----- includes/Maps_DisplayMapRenderer.php | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Maps_Settings.php b/Maps_Settings.php index 9e54375ce..6d3dab953 100644 --- a/Maps_Settings.php +++ b/Maps_Settings.php @@ -356,10 +356,5 @@ 'MapQuestOpen' => '', ]; - // Layer dependencies - $GLOBALS['egMapsLeafletLayerDependencies'] = [ - 'MapQuestOpen' => "", - ]; - $GLOBALS['egMapsGlobalJSVars'] = []; diff --git a/includes/Maps_DisplayMapRenderer.php b/includes/Maps_DisplayMapRenderer.php index 8268f0c90..936ca4925 100644 --- a/includes/Maps_DisplayMapRenderer.php +++ b/includes/Maps_DisplayMapRenderer.php @@ -148,7 +148,7 @@ protected function handleMarkerData( array &$params, Parser $parser ) { } else if ( $params['mappingservice'] === 'leaflet' ) { global $egMapsLeafletLayerDependencies; $layerDependencies = []; - $layerDependencies[] = $egMapsLeafletLayerDependencies['MapQuestOpen']; + $layerDependencies[] = ""; MapsMappingServices::getServiceInstance( 'leaflet' )->addLayerDependencies( array_unique( $layerDependencies ) ); From 51607cc606514f85436ae7a7ac7a5e64184bbd45 Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Mon, 12 Sep 2016 17:26:44 +0200 Subject: [PATCH 06/10] load leaflet layer dependencies in renderMap function --- includes/Maps_DisplayMapRenderer.php | 40 +++++++++++++--------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/includes/Maps_DisplayMapRenderer.php b/includes/Maps_DisplayMapRenderer.php index 936ca4925..a237d5a44 100644 --- a/includes/Maps_DisplayMapRenderer.php +++ b/includes/Maps_DisplayMapRenderer.php @@ -88,6 +88,12 @@ public final function renderMap( array $params, Parser $parser ) { $configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() ); + if ( isset( $params['layer'] ) ) { + $params['layers'] = [$params['layer']]; + } + $layerDependencies = self::getLayerDependencies( $params['mappingservice'], $params['layers'] ); + $this->service->addLayerDependencies( array_unique( $layerDependencies ) ); + $this->service->addDependencies( $parser ); $parser->getOutput()->addHeadItem( $configVars ); @@ -145,13 +151,6 @@ protected function handleMarkerData( array &$params, Parser $parser ) { if ( $params['mappingservice'] === 'openlayers' ) { $params['layers'] = self::evilOpenLayersHack( $params['layers'] ); - } else if ( $params['mappingservice'] === 'leaflet' ) { - global $egMapsLeafletLayerDependencies; - $layerDependencies = []; - $layerDependencies[] = ""; - MapsMappingServices::getServiceInstance( 'leaflet' )->addLayerDependencies( - array_unique( $layerDependencies ) - ); } } @@ -232,28 +231,27 @@ public static function evilOpenLayersHack( $layers ) { } } } - - MapsMappingServices::getServiceInstance( 'openlayers' )->addLayerDependencies( self::getLayerDependencies( $layerNames ) ); - return $layerDefs; } - /** - * FIXME - * @see evilOpenLayersHack - */ - private static function getLayerDependencies( array $layerNames ) { + public static function getLayerDependencies( $service, array $layerNames ) { global $egMapsOLLayerDependencies, $egMapsOLAvailableLayers; $layerDependencies = []; - foreach ( $layerNames as $layerName ) { - if ( array_key_exists( $layerName, $egMapsOLAvailableLayers ) // The layer must be defined in php - && is_array( $egMapsOLAvailableLayers[$layerName] ) // The layer must be an array... - && count( $egMapsOLAvailableLayers[$layerName] ) > 1 // ...with a second element... - && array_key_exists( $egMapsOLAvailableLayers[$layerName][1], $egMapsOLLayerDependencies ) ) { //...that is a dependency. - $layerDependencies[] = $egMapsOLLayerDependencies[$egMapsOLAvailableLayers[$layerName][1]]; + if ( $service === 'leaflet' && in_array( 'MapQuestOpen', $layerNames ) ) { + $layerDependencies[] = ""; + } else if ( $service === 'openlayers' ) { + foreach ( $layerNames as $layerName ) { + if ( array_key_exists( $layerName, $egMapsOLAvailableLayers ) // The layer must be defined in php + && is_array( $egMapsOLAvailableLayers[$layerName] ) // The layer must be an array... + && count( $egMapsOLAvailableLayers[$layerName] ) > 1 // ...with a second element... + && array_key_exists( $egMapsOLAvailableLayers[$layerName][1], $egMapsOLLayerDependencies ) ) { //...that is a dependency. + $layerDependencies[] = $egMapsOLLayerDependencies[$egMapsOLAvailableLayers[$layerName][1]]; + } } + } return array_unique( $layerDependencies ); From 58efc265d3afc4a0236e484e70014a46325b24cf Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Tue, 13 Sep 2016 14:28:43 +0200 Subject: [PATCH 07/10] move addLayerDependencies to MappingService --- includes/Maps_MappingService.php | 13 ++++++++++++- includes/services/Leaflet/Maps_Leaflet.php | 13 ------------- includes/services/OpenLayers/Maps_OpenLayers.php | 13 ------------- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/includes/Maps_MappingService.php b/includes/Maps_MappingService.php index 6e38662ad..576af8877 100644 --- a/includes/Maps_MappingService.php +++ b/includes/Maps_MappingService.php @@ -247,6 +247,17 @@ public final function addDependency( $dependencyHtml ) { $this->dependencies[] = $dependencyHtml; } + /** + * Adds the layer dependencies. + * + * @param array $dependencies + */ + public function addLayerDependencies( array $dependencies ) { + foreach ( $dependencies as $dependency ) { + $this->addDependency( $dependency ); + } + } + /** * @see iMappingService::getEarthZoom * @@ -256,4 +267,4 @@ public function getEarthZoom() { return 1; } -} \ No newline at end of file +} diff --git a/includes/services/Leaflet/Maps_Leaflet.php b/includes/services/Leaflet/Maps_Leaflet.php index fcafcdd60..08563296b 100644 --- a/includes/services/Leaflet/Maps_Leaflet.php +++ b/includes/services/Leaflet/Maps_Leaflet.php @@ -145,17 +145,4 @@ protected function getDependencies() { ]; } - /** - * Adds the layer dependencies. - * - * @since 3.8 - * - * @param array $dependencies - */ - public function addLayerDependencies( array $dependencies ) { - foreach ( $dependencies as $dependency ) { - $this->addDependency( $dependency ); - } - } - } diff --git a/includes/services/OpenLayers/Maps_OpenLayers.php b/includes/services/OpenLayers/Maps_OpenLayers.php index 129719d69..be664f696 100644 --- a/includes/services/OpenLayers/Maps_OpenLayers.php +++ b/includes/services/OpenLayers/Maps_OpenLayers.php @@ -158,19 +158,6 @@ public static function getLayerNames( $includeGroups = false ) { return $keys; } - /** - * Adds the layer dependencies. - * - * @since 0.7.1 - * - * @param array $dependencies - */ - public function addLayerDependencies( array $dependencies ) { - foreach ( $dependencies as $dependency ) { - $this->addDependency( $dependency ); - } - } - /** * @see MapsMappingService::getResourceModules * From 6b885720ffd10dbfe65ef254e601887257786878 Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Tue, 13 Sep 2016 15:21:27 +0200 Subject: [PATCH 08/10] cleanup loading of layer dependencies --- Maps_Settings.php | 5 ++++ includes/Maps_DisplayMapRenderer.php | 26 +++++++++++++-------- includes/services/Leaflet/jquery.leaflet.js | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Maps_Settings.php b/Maps_Settings.php index 6d3dab953..49e12634d 100644 --- a/Maps_Settings.php +++ b/Maps_Settings.php @@ -356,5 +356,10 @@ 'MapQuestOpen' => '', ]; + // Layer dependencies + $GLOBALS['egMapsLeafletLayerDependencies'] = [ + 'MapQuestOpen' => 'https://open.mapquestapi.com/sdk/leaflet/v2.2/mq-map.js?key=', + ]; + $GLOBALS['egMapsGlobalJSVars'] = []; diff --git a/includes/Maps_DisplayMapRenderer.php b/includes/Maps_DisplayMapRenderer.php index a237d5a44..5bcd62a12 100644 --- a/includes/Maps_DisplayMapRenderer.php +++ b/includes/Maps_DisplayMapRenderer.php @@ -88,11 +88,9 @@ public final function renderMap( array $params, Parser $parser ) { $configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() ); - if ( isset( $params['layer'] ) ) { - $params['layers'] = [$params['layer']]; - } - $layerDependencies = self::getLayerDependencies( $params['mappingservice'], $params['layers'] ); - $this->service->addLayerDependencies( array_unique( $layerDependencies ) ); + $this->service->addLayerDependencies( + self::getLayerDependencies( $params['mappingservice'], $params ) + ); $this->service->addDependencies( $parser ); $parser->getOutput()->addHeadItem( $configVars ); @@ -234,15 +232,23 @@ public static function evilOpenLayersHack( $layers ) { return $layerDefs; } - public static function getLayerDependencies( $service, array $layerNames ) { - global $egMapsOLLayerDependencies, $egMapsOLAvailableLayers; + public static function getLayerDependencies( $service, $params ) { + global $egMapsOLLayerDependencies, $egMapsOLAvailableLayers, + $egMapsLeafletLayerDependencies, $egMapsLeafletAvailableLayers, + $egMapsLeafletLayersApiKeys; $layerDependencies = []; - if ( $service === 'leaflet' && in_array( 'MapQuestOpen', $layerNames ) ) { - $layerDependencies[] = ""; + if ( $service === 'leaflet' ) { + $layerName = $params['layer']; + if ( in_array( $layerName, $egMapsLeafletAvailableLayers ) + && array_key_exists( $layerName, $egMapsLeafletLayersApiKeys ) + && array_key_exists( $layerName, $egMapsLeafletLayerDependencies ) ) { + $layerDependencies[] = ''; + } } else if ( $service === 'openlayers' ) { + $layerNames = $params['layers']; foreach ( $layerNames as $layerName ) { if ( array_key_exists( $layerName, $egMapsOLAvailableLayers ) // The layer must be defined in php && is_array( $egMapsOLAvailableLayers[$layerName] ) // The layer must be an array... diff --git a/includes/services/Leaflet/jquery.leaflet.js b/includes/services/Leaflet/jquery.leaflet.js index 37153a7dd..8451a622e 100644 --- a/includes/services/Leaflet/jquery.leaflet.js +++ b/includes/services/Leaflet/jquery.leaflet.js @@ -367,4 +367,4 @@ return this; }; -})(jQuery, window.mediaWiki, L, MQ); +})(jQuery, window.mediaWiki, L, window.MQ); From f372909ace3d682a423e3283e0c35eab7c1b331c Mon Sep 17 00:00:00 2001 From: PeterTheOne Date: Tue, 13 Sep 2016 15:30:17 +0200 Subject: [PATCH 09/10] change layers settings to array of booleans --- Maps_Settings.php | 70 +++++++++++----------- includes/Maps_DisplayMapRenderer.php | 3 +- includes/services/Leaflet/Maps_Leaflet.php | 4 +- 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/Maps_Settings.php b/Maps_Settings.php index 49e12634d..08f045f25 100644 --- a/Maps_Settings.php +++ b/Maps_Settings.php @@ -311,44 +311,44 @@ // The definitions for the layers that should be available for the user. $GLOBALS['egMapsLeafletAvailableLayers'] = [ - 'OpenStreetMap', - 'OpenStreetMap.DE', - 'OpenStreetMap.BlackAndWhite', - 'OpenStreetMap.HOT', - 'Thunderforest.OpenCycleMap', - 'Thunderforest.Transport', - 'Thunderforest.Landscape', - 'Hydda.Full', - //'MapBox', - 'Stamen.Toner', - 'Stamen.Terrain', - 'Stamen.Watercolor', - 'Esri.WorldStreetMap', - 'Esri.DeLorme', - 'Esri.WorldTopoMap', - 'Esri.WorldImagery', - 'Esri.WorldTerrain', - 'Esri.WorldShadedRelief', - 'Esri.WorldPhysical', - 'Esri.OceanBasemap', - 'Esri.NatGeoWorldMap', - 'Esri.WorldGrayCanvas', - 'MapQuestOpen', + 'OpenStreetMap' => true, + 'OpenStreetMap.DE' => true, + 'OpenStreetMap.BlackAndWhite' => true, + 'OpenStreetMap.HOT' => true, + 'Thunderforest.OpenCycleMap' => true, + 'Thunderforest.Transport' => true, + 'Thunderforest.Landscape' => true, + 'Hydda.Full' => true, + //'MapBox' => false, // todo: implement setting api key + 'Stamen.Toner' => true, + 'Stamen.Terrain' => true, + 'Stamen.Watercolor' => true, + 'Esri.WorldStreetMap' => true, + 'Esri.DeLorme' => true, + 'Esri.WorldTopoMap' => true, + 'Esri.WorldImagery' => true, + 'Esri.WorldTerrain' => true, + 'Esri.WorldShadedRelief' => true, + 'Esri.WorldPhysical' => true, + 'Esri.OceanBasemap' => true, + 'Esri.NatGeoWorldMap' => true, + 'Esri.WorldGrayCanvas' => true, + 'MapQuestOpen' => true, ]; $GLOBALS['egMapsLeafletAvailableOverlayLayers'] = [ - 'OpenSeaMap', - 'OpenWeatherMap.Clouds', - 'OpenWeatherMap.CloudsClassic', - 'OpenWeatherMap.Precipitation', - 'OpenWeatherMap.PrecipitationClassic', - 'OpenWeatherMap.Rain', - 'OpenWeatherMap.RainClassic', - 'OpenWeatherMap.Pressure', - 'OpenWeatherMap.PressureContour', - 'OpenWeatherMap.Wind', - 'OpenWeatherMap.Temperature', - 'OpenWeatherMap.Snow', + 'OpenSeaMap' => true, + 'OpenWeatherMap.Clouds' => true, + 'OpenWeatherMap.CloudsClassic' => true, + 'OpenWeatherMap.Precipitation' => true, + 'OpenWeatherMap.PrecipitationClassic' => true, + 'OpenWeatherMap.Rain' => true, + 'OpenWeatherMap.RainClassic' => true, + 'OpenWeatherMap.Pressure' => true, + 'OpenWeatherMap.PressureContour' => true, + 'OpenWeatherMap.Wind' => true, + 'OpenWeatherMap.Temperature' => true, + 'OpenWeatherMap.Snow' => true, ]; $GLOBALS['egMapsLeafletLayersApiKeys'] = [ diff --git a/includes/Maps_DisplayMapRenderer.php b/includes/Maps_DisplayMapRenderer.php index 5bcd62a12..1792b693e 100644 --- a/includes/Maps_DisplayMapRenderer.php +++ b/includes/Maps_DisplayMapRenderer.php @@ -241,7 +241,8 @@ public static function getLayerDependencies( $service, $params ) { if ( $service === 'leaflet' ) { $layerName = $params['layer']; - if ( in_array( $layerName, $egMapsLeafletAvailableLayers ) + if ( array_key_exists( $layerName, $egMapsLeafletAvailableLayers ) + && $egMapsLeafletAvailableLayers[$layerName] && array_key_exists( $layerName, $egMapsLeafletLayersApiKeys ) && array_key_exists( $layerName, $egMapsLeafletLayerDependencies ) ) { $layerDependencies[] = '