diff --git a/config.toml b/config.toml index a3f3a1cc..1d8e0b73 100644 --- a/config.toml +++ b/config.toml @@ -178,23 +178,29 @@ greyColorDark = "#A0A0A0" URL = "/about/community" weight = 2 + [[Languages.en.menu.main]] + parent = "About" + name = "Community map" + URL = "/about/map" + weight = 3 + [[Languages.en.menu.main]] parent = "About" name = "History" URL = "/about/history" - weight = 3 + weight = 4 [[Languages.en.menu.main]] parent = "About" name = "Brand" URL = "/about/brand" - weight = 4 + weight = 5 [[Languages.en.menu.main]] parent = "About" name = "Credits" URL = "/about/credits" - weight = 5 + weight = 6 # banner [Languages.en.params.banner] diff --git a/content/about/map.md b/content/about/map.md new file mode 100644 index 00000000..efc5861a --- /dev/null +++ b/content/about/map.md @@ -0,0 +1,8 @@ +--- +title: "GRASS GIS community map" +date: 2018-12-29T11:02:05+06:00 +layout: "map" +--- + +### Add your self +To add yourself to the GRASS GIS user map you need to follow [these instructions](https://github.com/OSGeo/grass-website/static/geojson/README.md) diff --git a/static/geojson/README.md b/static/geojson/README.md new file mode 100644 index 00000000..aa687d43 --- /dev/null +++ b/static/geojson/README.md @@ -0,0 +1,69 @@ +# GRASS GIS map + +In this folder you can find geographical data related to GRASS GIS community. The data are provided in GeoJSON format. + +## User map + +The [user.geojson file](https://github.com/OSGeo/grass-website/static/geojson/user.geojson) contain the position of GRASS GIS users. +The [provider.geojson file](https://github.com/OSGeo/grass-website/static/geojson/provider.geojson) contain the position of any companies, +research center, university providing activities (specially development and courses) related to GRASS GIS. + +## Add new record + +If you want to add a new record to one of the GeoJSON files you have to ways + +### User without Git/Github experience + +* You need to create a [Github account](https://github.com/join) +* Sign in and move to https://github.com/OSGeo/grass-website/ repository +* Choose the file to modify into [GeoJSON files](https://github.com/OSGeo/grass-website/static/geojson/) +* Click the pencil button to modify the file +* Add a new feature copying the feature template in the bottom of the page +* When you save the file, select `Create a new branch for this commit and start a pull request.` + +### Git/Github advanced user + +* Fork the https://github.com/OSGeo/grass-website/ repository +* Create a new branch +* Add a new feature copying the feature template in the bottom of the page +* Commit, push the modified file +* Create a pull request + +## Templates + +### User + + { + "type": "Feature", + "properties": { + "name": "NAME_SURNAME", + "url": "YOUR_URL_NOT_REQUIRED", + "image": "URL_TO_YOUR_IMAGE_NOT_REQUIRED" + }, + "geometry": { + "type": "Point", + "coordinates": [ + LONGITUDE, + LATITUDE + ] + } + } + +### Provider + + { + "type": "Feature", + "properties": { + "name": "NAME_SURNAME", + "url": "YOUR_URL_NOT_REQUIRED", + "image": "URL_TO_YOUR_IMAGE_NOT_REQUIRED", + "description": "SHORT_DESCRIPTION_YOUR_ACTIVITY_IN_GRASS" + }, + "geometry": { + "type": "Point", + "coordinates": [ + LONGITUDE, + LATITUDE + ] + } + } \ No newline at end of file diff --git a/static/geojson/provider.geojson b/static/geojson/provider.geojson new file mode 100644 index 00000000..c429f047 --- /dev/null +++ b/static/geojson/provider.geojson @@ -0,0 +1,21 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "name": "Mundialis", + "url": "https://www.mundialis.de/en/", + "image": "https://www.mundialis.de/wordpress/wp-content/uploads/2015/11/mundialis_logo.png", + "description": "" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 7.0968584, + 50.7409291 + ] + } + } + ] +} diff --git a/static/geojson/user.geojson b/static/geojson/user.geojson new file mode 100644 index 00000000..b75f45f0 --- /dev/null +++ b/static/geojson/user.geojson @@ -0,0 +1,20 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "name": "Luca Delucchi", + "url": "http://www.lucadelu.org", + "image": "" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 11.111061573028564, + 46.13950796157218 + ] + } + } + ] +} diff --git a/themes/grass/assets/css/style.css b/themes/grass/assets/css/style.css index 2799161f..259b8f8b 100644 --- a/themes/grass/assets/css/style.css +++ b/themes/grass/assets/css/style.css @@ -895,6 +895,62 @@ code{ font-size: 7em; } +#map{ + height: 80vh; + width: 100%; +} + +.ol-popup { + position: absolute; + background-color: white; + box-shadow: 0 1px 4px rgba(0,0,0,0.2); + padding: 15px; + border-radius: 10px; + border: 1px solid #cccccc; + bottom: 12px; + left: -50px; + min-width: 280px; +} +.ol-popup:after, .ol-popup:before { + top: 100%; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; +} +.ol-popup:after { + border-top-color: white; + border-width: 10px; + left: 48px; + margin-left: -10px; +} +.ol-popup:before { + border-top-color: #cccccc; + border-width: 11px; + left: 48px; + margin-left: -11px; +} +.ol-popup-closer { + text-decoration: none; + position: absolute; + top: 2px; + right: 8px; +} +.ol-popup-closer:after { + content: "✖"; +} + +#popup-content p, #popup-content img { + margin-bottom: 0; + font-size: 20px; + font-weight: bolder; +} + +input[type='radio']{ + margin-right: 0.5rem; +} @media (max-width: 576px) { diff --git a/themes/grass/assets/js/map.js b/themes/grass/assets/js/map.js new file mode 100644 index 00000000..4ba3aa56 --- /dev/null +++ b/themes/grass/assets/js/map.js @@ -0,0 +1,138 @@ + +(function ($) { + var oldfeat; + var vecturl='/geojson/user.geojson'; + var container = document.getElementById('popup'); + var content = document.getElementById('popup-content'); + var closer = document.getElementById('popup-closer'); + + /** + * Create an overlay to anchor the popup to the map. + */ + var overlay = new ol.Overlay({ + element: container, + autoPan: true, + autoPanAnimation: { + duration: 250 + } + }); + + + /** + * Add a click handler to hide the popup. + * @return {boolean} Don't follow the href. + */ + closer.onclick = function() { + overlay.setPosition(undefined); + closer.blur(); + if (oldfeat) { + oldfeat.setStyle(defaultStyle); + oldfeat = null; + } + return false; + }; + + var defaultStyle = new ol.style.Style({ + image: new ol.style.Circle({ + radius: 4, + fill: new ol.style.Fill({ + color: 'rgb(255, 255, 255)' + }), + stroke: new ol.style.Stroke({ + color: '#088B36', + width: 2 + }) + }) + }); + + var highlightStyle = new ol.style.Style({ + image: new ol.style.Circle({ + radius: 8, + fill: new ol.style.Fill({ + color: 'rgb(255, 255, 255)' + }), + stroke: new ol.style.Stroke({ + color: '#088B36', + width: 3 + }) + }) + }); + + var vsource = new ol.source.Vector({ + url: vecturl, + format: new ol.format.GeoJSON() + }); + + var vectorLayer = new ol.layer.Vector({ + source: vsource, + style: defaultStyle, + title: 'Users' + }); + var map = new ol.Map({ + layers: [ + new ol.layer.Tile({ + source: new ol.source.OSM() + }), + vectorLayer + ], + target: 'map', + overlays: [overlay], + controls: ol.control.defaults({ + attributionOptions: /** @type {olx.control.AttributionOptions} */ ({ + collapsible: false + }) + }), + view: new ol.View({ + center: ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857'), + zoom: 2 + }) + }); + map.on('click', function(evt) { + var coordinate = evt.coordinate; + feat = map.forEachFeatureAtPixel(evt.pixel, + function(feature, vectorLayer) { + return feature + } + ) + if (feat) { + feat.setStyle(highlightStyle); + oldfeat = feat; + var mycontent = '

'; + var userurl = feat.get('url') + var userimage = feat.get('image') + if (userimage) { + mycontent += '' + } + if (userurl) { + mycontent += '' + feat.get('name') + '

'; + } else { + mycontent += feat.get('name') + '

'; + } + var userdesc = feat.get('description') + if (userdesc) { + mycontent += '

' + userdesc + '

'; + } + content.innerHTML = mycontent + overlay.setPosition(coordinate); + } else { + if (oldfeat) { + oldfeat.setStyle(defaultStyle); + oldfeat = null; + } + } + }) + $("input[name='layers']").each( function () { + //console.log($(this)[0]); + $(this)[0].addEventListener('change', function () { + var ingeojson = $(this).val(); + vecturl = '/geojson/' + ingeojson + '.geojson' + vsource = new ol.source.Vector({ + url: vecturl, + format: new ol.format.GeoJSON(), + }); + vectorLayer.setSource(vsource); + vectorLayer.getSource().refresh(); + vectorLayer.getSource().changed(); + }) + }); +})(jQuery); \ No newline at end of file diff --git a/themes/grass/layouts/about/map.html b/themes/grass/layouts/about/map.html new file mode 100644 index 00000000..d3205494 --- /dev/null +++ b/themes/grass/layouts/about/map.html @@ -0,0 +1,48 @@ +{{ partial "head.html" . }} + + +{{ "" | safeHTML }} +
+
+ {{ partial "navigation.html" . }} +
+
+{{ "" | safeHTML }} + + + +
+
+
+
+

{{.Title}}

+
+
+
+
+
+ {{ partial "breadcrumb.html" . }} +
+ + +
+
+
+
+
+ +
+ +
+

Layer Manager

+ Users
+ Provider
+ {{ .Content }} +
+
+
+ +{{ partial "footer.html" . }} \ No newline at end of file diff --git a/themes/grass/layouts/partials/footer.html b/themes/grass/layouts/partials/footer.html index 14719e92..f4222927 100644 --- a/themes/grass/layouts/partials/footer.html +++ b/themes/grass/layouts/partials/footer.html @@ -33,7 +33,11 @@ {{ $script := resources.Get "js/script.js" | minify}} - +{{ if eq .URL "/about/map/" }} +{{ "" | safeHTML }} +{{ $script := resources.Get "js/map.js" | minify}} + +{{ end }} \ No newline at end of file diff --git a/themes/grass/layouts/partials/head.html b/themes/grass/layouts/partials/head.html index 96b3be10..4834e7c4 100644 --- a/themes/grass/layouts/partials/head.html +++ b/themes/grass/layouts/partials/head.html @@ -19,7 +19,10 @@ - + {{ if eq .URL "/about/map/" }} + + + {{ end }}