CruisersWiki:Ol3chartlet.js

From CruisersWiki

(Difference between revisions)
Jump to: navigation, search
(Ol3chartlet features release)
Line 8: Line 8:
(function() {
(function() {
-
 
     var nx = {
     var nx = {
         navKey: 'Navionics_webapi_00572',
         navKey: 'Navionics_webapi_00572',
Line 21: Line 20:
     };
     };
 +
    nx.navTokenPending = [];
 +
   
     nx.init = function(callback) {
     nx.init = function(callback) {
         // set location for Navionics images
         // set location for Navionics images
Line 28: Line 29:
             callback();
             callback();
         } else {
         } else {
 +
            callback && nx.navTokenPending.push(callback);
             // requestNavToken
             // requestNavToken
             var targetUrl = nx.BASE_TILE_SERVER + nx.KEY_REQ_SUFFIX;
             var targetUrl = nx.BASE_TILE_SERVER + nx.KEY_REQ_SUFFIX;
Line 35: Line 37:
                 crossDomain: true,
                 crossDomain: true,
                 dataType: 'text',
                 dataType: 'text',
-
                 cache: false,
+
                 //cache: false,
                 error: function() {
                 error: function() {
                   return console.log(arguments);
                   return console.log(arguments);
Line 41: Line 43:
                 success: function(data, textStatus, jqXHR) {
                 success: function(data, textStatus, jqXHR) {
                     nx.navToken = data;
                     nx.navToken = data;
-
                     callback();
+
                     for (var i=0; i < nx.navTokenPending.length; i++ )  
 +
                        nx.navTokenPending[i]();
 +
                    nx.navTokenPending = [];
                 }
                 }
             });
             });
Line 140: Line 144:
         })
         })
     };
     };
 +
   
 +
    var baselayersGroupName = 'Base';
 +
    var overlaysGroupName = 'Overlays';
     function ol3Chartlet(chartlet_div) {
     function ol3Chartlet(chartlet_div) {
Line 162: Line 169:
         }
         }
-
         this.params = parseParams(standalone && location.hash ? decodeURIComponent(location.hash.slice(1)) : $(chartlet_div).text());
+
         this.params = parseParams(standalone && location.hash ? decodeURI(location.hash.slice(1)) : $(chartlet_div).text());
 +
        this.params.standalone = standalone;
         var iconFeature = new ol.Feature({
         var iconFeature = new ol.Feature({
Line 214: Line 222:
         });
         });
-
         var overLayers = standalone ? [
+
         var overLayers = standalone || this.params.pageFeatures ? [
             openseamap,
             openseamap,
             nx_layer_ovl,
             nx_layer_ovl,
Line 254: Line 262:
         });
         });
-
         var baseLayers =  standalone ? [
+
         var baseLayers =  standalone || this.params.pageFeatures ? [
             osm,
             osm,
             esri_world,
             esri_world,
Line 275: Line 283:
         var layers = [
         var layers = [
             new ol.layer.Group({
             new ol.layer.Group({
-
                 'title': 'Base map',
+
                 title: baselayersGroupName,
                 layers: baseLayers
                 layers: baseLayers
             })
             })
         ];
         ];
-
         if (overLayers.length > 0 )
+
         if (overLayers.length > 0 || this.params.pageFeatures)
             layers.push(new ol.layer.Group({
             layers.push(new ol.layer.Group({
-
                     title: 'Layers',
+
                     title: overlaysGroupName,
                     layers: overLayers
                     layers: overLayers
             }));
             }));
Line 319: Line 327:
         if (standalone) {
         if (standalone) {
-
             this.initStandalone();
+
             this.params.page && this.loadFeatures();
 +
            this.trackHash();
 +
            this.addGraticule();
 +
        } else if (this.params.pageFeatures) {
 +
            this.loadFeatures();
         }
         }
     };
     };
-
     // add layer to a layer group
+
     // add to a layer group
     ol3Chartlet.prototype.addNonBaseLayer = function (new_layer) {
     ol3Chartlet.prototype.addNonBaseLayer = function (new_layer) {
         this.map.getLayers().forEach(
         this.map.getLayers().forEach(
             function(layer) {
             function(layer) {
-
                 if (layer.get('title') === 'Layers') {
+
                 if (layer.get('title') === overlaysGroupName) {
                     layer.getLayers().push(new_layer);
                     layer.getLayers().push(new_layer);
                 }
                 }
             }
             }
         );
         );
-
    }
 
-
 
-
    ol3Chartlet.prototype.initStandalone = function () {
 
-
 
-
        this.trackHash()
 
-
        this.addGraticule();
 
-
 
-
        var page = this.params.page;
 
-
        var _this = this;
 
-
 
-
        if (page) {
 
-
            loadWikiScript('CruisersWiki:GetKml.js', function () {
 
-
                getKml(
 
-
                    {
 
-
                        page: page,
 
-
                        decorated: true
 
-
                    },
 
-
                    _this.addPOIs.bind(_this)
 
-
                );
 
-
            });
 
-
 
-
            loadWikiCss('CruisersWiki:Ol3-popup.css');
 
-
            loadWikiScript("CruisersWiki:Ol3-popup.js", _this.initPopups.bind(_this));
 
-
        }
 
     };
     };
Line 400: Line 388:
                 return;
                 return;
             }
             }
-
             params = parseParams(decodeURIComponent(location.hash.slice(1)));
+
             params = parseParams(location.hash.slice(1));
             if (params.lat != null && params.lon != null) {
             if (params.lat != null && params.lon != null) {
                 var centre = [params.lon, params.lat];
                 var centre = [params.lon, params.lat];
Line 409: Line 397:
     };
     };
-
     // add coordinate grid layer
+
     // Create the graticule
     ol3Chartlet.prototype.addGraticule = function () { // after http://map.openseamap.org/javascript/grid_wgs.js
     ol3Chartlet.prototype.addGraticule = function () { // after http://map.openseamap.org/javascript/grid_wgs.js
-
         var gridSteps = [
+
         var this_ = this;
-
            // in seconds
+
         loadWikiScript('CruisersWiki:Ol3chartlet/graticule.js', function () {
-
            //~ 3 / 3600,        // 0.05'
+
             var layer = graticuleLayer(this_.map);
-
            6 / 3600, 12 / 3600, 30 / 3600,  // 0.1'  0.2'  0.5'
+
             this_.addNonBaseLayer(layer);
-
            // in minutes
+
         });
-
            1 / 60, 2 / 60, 3 / 60, 5 / 60, 10 / 60, 20 / 60, 30 / 60,
+
         /*
-
            // in degrees
+
         var graticule = new ol.Graticule({
-
            1, 2, 3, 4, 6, 10, 15, 30, 45];
+
             map: this.map,
-
 
+
             // the style to use for the lines, optional.
-
         var gridPixelStep = 100;
+
             strokeStyle: new ol.style.Stroke({
-
 
+
                 color: 'rgba(255,120,0,0.9)',
-
        // Find matching grid step
+
                 width: 2,
-
        var getGridStep = function (distance) {
+
                 lineDash: [0.5, 4]
-
            for (var i=0; i<gridSteps.length; i++) {
+
-
                if (distance < gridSteps[i])
+
-
                    return gridSteps[i];
+
-
            }
+
-
            return gridSteps[i-1];
+
-
        };
+
-
 
+
-
        // Format label
+
-
        var zeroPad = function (x, int_places, dec, zero_pad) {
+
-
            var pad = '                    ' // spaces there
+
-
            var sign = ''
+
-
            var places = dec > 0 ? int_places+dec+1 : int_places
+
-
            if (zero_pad == null || zero_pad) {
+
-
                var pad = '00000000000000000000'
+
-
                if (x < 0) {
+
-
                    x = Math.abs(x)
+
-
                    places--
+
-
                    sign = '-'
+
-
                }
+
-
            }
+
-
            return sign + (pad + x.toFixed(dec)).slice(-places)
+
-
        };
+
-
 
+
-
        var formatDegrees = function (deg, format, isLon) {
+
-
             var adeg = Math.abs(deg);
+
-
             return ''
+
-
                + zeroPad(Math.floor(adeg), isLon ? 3 : 2) + "°"
+
-
                + (format == 'd' ? '' : zeroPad((adeg * 60) % 60, 2, format == 'dm' ? 0 : 1) + "'")
+
-
                + (isLon ? (deg < 0 ? 'W' : 'E') : (deg < 0 ? 'S' : 'N'));
+
-
         };
+
-
 
+
-
        var map = this.map;
+
-
        var view = this.map.getView();
+
-
 
+
-
         // layer loader
+
-
         var loader = function(extent, resolution, projection) {
+
-
            /**
+
-
            * @param {ol.Extent} extent Extent.
+
-
            * @param {number} resolution Resolution.
+
-
             * @param {ol.proj.Projection} projection Projection.
+
-
            * @this {ol.source.Vector|ol.VectorTile}
+
-
            */
+
-
            var view_proj = view.getProjection();
+
-
            var geo_proj = 'EPSG:4326';
+
-
            var map_size = map.getSize();
+
-
 
+
-
            var lonlat_extent = ol.proj.transformExtent(extent, view_proj, geo_proj);
+
-
 
+
-
             // clip extent to max values
+
-
            var x1 = Math.max (-180, lonlat_extent[0]);
+
-
            var x2 = Math.min ( 180, lonlat_extent[2]);
+
-
             var y1 = Math.max ( -85, lonlat_extent[1]);
+
-
            var y2 = Math.min (  85, lonlat_extent[3]);
+
-
 
+
-
            // grid step
+
-
            var step = getGridStep((lonlat_extent[3] - lonlat_extent[1]) / map_size[1] * gridPixelStep);
+
-
 
+
-
            var labelFormat = step % 1 ? ((step * 60)% 1 ? 'dm.m' : 'dm') : 'd'; //  round degrees number
+
-
 
+
-
            var features = [];
+
-
 
+
-
            // line style
+
-
            var strokeStyle = new ol.style.Stroke({
+
-
                 color: [102, 102, 102, 255 * 0.8], // "#666666",
+
-
                width: 1,
+
-
                //~ strokeOpacity: 0.8
+
-
            });
+
-
 
+
-
            // Vertical lines
+
-
            for (var x = Math.ceil(x1 / step) * step + (x1 == -180 ? step : 0); x <= x2; x += step) {
+
-
                var l = new ol.geom.LineString([
+
-
                    ol.proj.transform([x, y1], geo_proj, view_proj),
+
-
                    ol.proj.transform([x, y2], geo_proj, view_proj)
+
-
                 ]);
+
-
                var f = new ol.Feature(l);
+
-
                f.setStyle(new ol.style.Style({
+
-
                    stroke: strokeStyle,
+
-
                    text: new ol.style.Text({
+
-
                        text: formatDegrees (x, labelFormat, true),
+
-
                        textAlign: 'end',
+
-
                        textBaseline: 'top',
+
-
                        offsetX: 0,
+
-
                        offsetY: - map_size[1] / 2,
+
-
                        rotation: - Math.PI / 2,
+
-
                        scale: 1.5,
+
-
                        // labelAlign: "lt",
+
-
                    }),
+
-
                 }));
+
-
                features.push (f);
+
-
            }
+
-
 
+
-
            // Horizontal lines
+
-
            for (var y = Math.ceil(y1 / step) * step; y <= y2; y += step) {
+
-
                var l = new ol.geom.LineString([
+
-
                    ol.proj.transform([x1, y], geo_proj, view_proj),
+
-
                    ol.proj.transform([x2, y], geo_proj, view_proj)
+
-
                ]);
+
-
                var f = new ol.Feature(l);
+
-
                f.setStyle(new ol.style.Style({
+
-
                    stroke: strokeStyle,
+
-
                    text: new ol.style.Text({
+
-
                        text: formatDegrees (y, labelFormat, false),
+
-
                        textAlign: 'end',
+
-
                        textBaseline: 'top',
+
-
                        offsetX: map_size[0] / 2,
+
-
                        offsetY: 0,
+
-
                        rotation: 0,
+
-
                        scale: 1.5,
+
-
                        //~ labelAlign: "lt",
+
-
                    }),
+
-
                }));
+
-
                features.push (f);
+
-
            }
+
-
 
+
-
            this.addFeatures(features);
+
-
        };
+
-
 
+
-
        var graticule = new ol.layer.Vector({
+
-
            title: 'Graticule',
+
-
            visible: false,
+
-
            source: new ol.source.Vector({
+
-
                loader: loader,
+
-
                strategy: ol.loadingstrategy.bbox
+
             })
             })
         });
         });
-
        graticule.set('noclickable', true);
+
         // graticule.setMap(this.map);
-
 
+
         */
-
         // add to the proper layer group
+
-
        this.addNonBaseLayer(graticule);
+
-
 
+
-
        var onChangeCenterZoom = function () {
+
-
            graticule.getSource().clear();
+
-
         }
+
-
        view.on('change:center', onChangeCenterZoom);
+
-
        view.on('change:resolution', onChangeCenterZoom);
+
     };
     };
-
    // load kml
+
     ol3Chartlet.prototype.loadFeatures = function (page) {
-
     ol3Chartlet.prototype.addPOIs = function(kml) {
+
         loadWikiScript('CruisersWiki:Ol3chartlet features.js', function () {
-
         if (!kml)
+
             var layer = getArticleLayer(this.params);
-
            return;
+
             this.addNonBaseLayer(layer);
-
        // kml_uri='http://openlayers.org/en/v3.13.1/examples/data/kml/2012-02-10.kml';
+
         }.bind(this));
-
        var format = new ol.format.KML({
+
-
            showPointNames: false,
+
-
        });
+
-
        var loader = function(extent, resolution, projection) {
+
-
            /**
+
-
            * @param {ol.Extent} extent Extent.
+
-
            * @param {number} resolution Resolution.
+
-
            * @param {ol.proj.Projection} projection Projection.
+
-
            * @this {ol.source.Vector|ol.VectorTile}
+
-
            */
+
-
             var xml_tree = ol.xml.parse(kml);
+
-
 
+
-
            var features = format.readFeatures(
+
-
                xml_tree,
+
-
                {featureProjection: projection}
+
-
            );
+
-
 
+
-
             this.addFeatures(features);
+
-
         };
+
-
        var kml_layer = new ol.layer.Vector({
+
-
            title: 'POI',
+
-
            visible:true,
+
-
            source: new ol.source.Vector({
+
-
                loader: loader,
+
-
            })
+
-
        });
+
-
         // add to the proper layer group
+
         loadWikiCss('CruisersWiki:Ol3-popup.css');
-
         this.addNonBaseLayer(kml_layer);
+
         loadWikiScript("CruisersWiki:Ol3-popup.js", this.initPopups.bind(this));
     };
     };
Line 606: Line 437:
             return ! layer.get('noclickable');
             return ! layer.get('noclickable');
         };
         };
 +
       
 +
        var popTemplate =
 +
            '<div class="cw-popup-name"><a href="{href}">{name}</a></div>\n' +
 +
            '<div class="cw-popup-category">{category}</div>\n' +
 +
            '<div class="cw-popup-content">{content}</div>';
         // display popup on click
         // display popup on click
Line 618: Line 454:
                 );
                 );
             if (feature && ! feature.get('noclickable')) {
             if (feature && ! feature.get('noclickable')) {
-
                 popup.show(evt.coordinate,
+
                 var data = {
-
                     '<div class="cw-popup-name">' + feature.get("name") + '</div>' +
+
                    href: feature.get("link"),
-
                     '<div class="cw-popup-category">' + feature.get("styleUrl").split('#')[1] + '</div>' +
+
                     name: feature.get("name"),
-
                     '<div class="cw-popup-content">' + feature.get("description") + '<div>'
+
                     category: feature.get("category"),
-
                 );
+
                     content: feature.get("description"),
 +
                 };
 +
                popup.show(evt.coordinate, format(popTemplate, data));
             } else {
             } else {
                 popup.hide();
                 popup.hide();
Line 646: Line 484:
             return deg;
             return deg;
-
         var parts = dmsh.replace(/[°′″'"]/g, '_').split('_');
+
         var parts = dmsh.split('_');
         for (var i=0, li = parts.length; i < li; i++) {
         for (var i=0, li = parts.length; i < li; i++) {
             var p = parts[i];
             var p = parts[i];
Line 663: Line 501:
     function parseParams(param_str) {
     function parseParams(param_str) {
-
         var out = {};
+
         var out = {
-
         var params = param_str.split('|');
+
            icons: true,
 +
            //recursive: 1,
 +
            //childrenlocations: true,
 +
            //captions: true,
 +
         };
 +
        var params = param_str.split('|');
         for (var i=0, li = params.length; i < li; i++) {
         for (var i=0, li = params.length; i < li; i++) {
             var keyVal = params[i].split('=', 2);
             var keyVal = params[i].split('=', 2);
Line 680: Line 523:
             } else if (key == 'page') {
             } else if (key == 'page') {
                 out.page = val;
                 out.page = val;
 +
            } else if (key == 'pagefeatures') {
 +
                out.pageFeatures = !!val;
 +
            } else if (key == 'captions') {
 +
                out.captions = !!val;
 +
            } else if (key == 'childrenlocations') {
 +
                out.childrenlocations = true;
 +
                out.recursive = 1;
 +
            } else if (key == 'icons') {
 +
                out.icons = !!val;
             }
             }
         }
         }
Line 691: Line 543:
     function chartletStart(secondCall) {
     function chartletStart(secondCall) {
-
         var $chartlets = $('.chartlet');
+
         var $chartlets = $('.chartlet-test');
         if ($chartlets.length === 0) {
         if ($chartlets.length === 0) {
             return;
             return;

Revision as of 14:33, 22 December 2016

//
/*
   ol3Chartlet.js

   Copyright (c) 2016 Vadim Shlyakhov
   Licensed MIT
*/

(function() {
    var nx = {
        navKey: 'Navionics_webapi_00572',
        domain: 'www.cruiserswiki.org',
        navToken: null,
        BASE_TILE_SERVER: '//backend.navionics.io',
        TILE_SUFFIX: '/tile/{z}/{x}/{y}',
        KEY_REQ_SUFFIX: '/tile/get_key',
        MAX_RESOLUTION: 20480,
        MIN_RESOLUTION: 0.625,
        disclaimer_msg: '<b>© Navionics</b> <a href="http://www.navionics.com/en/acknowledgements" target="_new" class="navionics-acknowledgements">Acknowledgements</a> | Not to be used for navigation',
    };

    nx.navTokenPending = [];
    
    nx.init = function(callback) {
        // set location for Navionics images
        //~ $('body').attr('data-root', 'http://webapiv2.navionics.com/dist/webapi/images');

        if ( nx.navToken ) {
            callback();
        } else {
            callback && nx.navTokenPending.push(callback);
            // requestNavToken
            var targetUrl = nx.BASE_TILE_SERVER + nx.KEY_REQ_SUFFIX;
            $.ajax({
                url: targetUrl + '/' + nx.navKey + '/' + nx.domain,
                async: !!callback,
                crossDomain: true,
                dataType: 'text',
                //cache: false,
                error: function() {
                  return console.log(arguments);
                },
                success: function(data, textStatus, jqXHR) {
                    nx.navToken = data;
                    for (var i=0; i < nx.navTokenPending.length; i++ ) 
                        nx.navTokenPending[i]();
                    nx.navTokenPending = [];
                }
            });
        }
    };

    nx.depthUnits = {
        'm': 1, 'metre': 1, 'meter': 1,
        'ft': 2, 'feet': 2,
        'fathom': 3,
    };

    nx.formatTileUrl = function (options) { // sonar, overlay, depthUnit, safeDepth, showUGC
        options = options || {};
        var layerConfig = [
            'config',
            nx.depthUnits[options.depthUnit] || 1,
            (options.safeDepth || 20).toFixed(2),
            options.sonar ? 1 : 0
        ];
        params = $.param({
            LAYERS: layerConfig.join('_'),
            TRANSPARENT: !! options.transparency,
            UGC: !! options.showUGC,
            navtoken: nx.navToken
        });
        return nx.BASE_TILE_SERVER + nx.TILE_SUFFIX + '?' + params;
    };

    nx.getTileUrl = function (options, callback) { // sonar, overlay, depthUnit, safeDepth, showUGC
        nx.init(function () {
            callback(nx.formatTileUrl(options))
        });
    };

    nx.new_source = function (options) {
        var source = new ol.source.XYZ({
            crossOrigin: 'anonymous',
            attributions: [
                new ol.Attribution({
                    html: nx.disclaimer_msg
                })
            ],
            maxResolution: nx.MAX_RESOLUTION,
            minResolution: nx.MIN_RESOLUTION
        });

        nx.getTileUrl(
            options,
            function (url) {
                source.setUrl(url);
            }
        );

        return source;
    };

    var esri = {};
    esri.uris = {
        'satellite': "http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
        'topo': "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",
        'terrain': 'http://server.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer',
        'physical': 'http://services.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer',
        'relief': 'http://server.arcgisonline.com/arcgis/rest/services/World_Shaded_Relief/MapServer',
        'light-gray': "http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer",
        'dark-gray': "http://services.arcgisonline.com/arcgis/rest/services/Canvas/World_Dark_Gray_Base/MapServer",
        'street': "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer",
        'hybrid': "http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer",
        'oceans-reference': "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer",
        'oceans': 'http://server.arcgisonline.com/arcgis/rest/services/Ocean_Basemap/MapServer',
        'national-geographic': "http://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
    };

    esri.ZZnew_source = function (src_id) {
        return new ol.source.TileArcGISRest({
            url: esri.uris[src_id],
            params: {
                FORMAT: 'JPG',
                TRANSPARENT: false,
            },
            attributions: [
                new ol.Attribution({
                    html: 'Tiles by ESRI <a href="' + esri.uris[src_id] + '">Acknowledgements</a>'
                })
            ]
        })
    };

    esri.new_source = function (src_id) {
        return new ol.source.XYZ({
            url: esri.uris[src_id] + '/tile/{z}/{y}/{x}',
            crossOrigin: null,
            attributions: [
                new ol.Attribution({
                    html: 'Tiles by ESRI <a href="' + esri.uris[src_id] + '">Acknowledgements</a>'
                })
            ],
        })
    };
    
    var baselayersGroupName = 'Base';
    var overlaysGroupName = 'Overlays';

    function ol3Chartlet(chartlet_div) {
        console.log('ol3Chartlet');

        var standalone_div = $('#chartlet-standalone')[0];
        var standalone = !! standalone_div;

        // if (standalone && location.hash) {
        //     $('body').empty().append(standalone_div);
        //     $('body').addClass('cw-chartlet-extend');
        // }
    
        // fill in to a full window if URL hash is set
        if (standalone && location.hash) {
            while (document.body.firstChild) {
                document.body.removeChild(document.body.firstChild);
            }
            document.body.appendChild(chartlet_div);

            $('body').addClass('cw-chartlet-extend');
        }

        this.params = parseParams(standalone && location.hash ? decodeURI(location.hash.slice(1)) : $(chartlet_div).text());
        this.params.standalone = standalone;

        var iconFeature = new ol.Feature({
            geometry: new ol.geom.Point(ol.proj.transform([this.params.lon, this.params.lat], 'EPSG:4326', 'EPSG:3857')),
            name: 'Test marker',
        });

        iconFeature.setStyle(
            new ol.style.Style({
                image: new ol.style.Icon({
                    anchor: [0, 1],
                    anchorXUnits: 'fraction',
                    anchorYUnits: 'fraction',
                    // anchorYUnits: 'pixels',
                    opacity: 1,
                    src: '/images/e/e7/Flag_icon.png'
                })
            })
        );

        var testLayer = new ol.layer.Vector({
            title: 'Icon',
            source: new ol.source.Vector({
                features: [iconFeature]
            })
        });

        var openseamap = new ol.layer.Tile({
            title: 'OpenSeaMap',
            visible: false,
            source: new ol.source.XYZ({
                url: 'http://t1.openseamap.org/seamark/{z}/{x}/{y}.png',
                crossOrigin: null,
                attributions: [
                    new ol.Attribution({
                        html: 'Tiles by <a href="http://www.openseamap.org">OpenSeaMap</a>'
                    })
                ],
            })
        });

        var nx_layer = new ol.layer.Tile({
            title: 'Navionics',
            source: nx.new_source()
        });
        var nx_layer_ovl = new ol.layer.Tile({
            title: 'Navionics Boating',
            source: nx.new_source({
                transparency:true
            })
        });

        var overLayers = standalone || this.params.pageFeatures ? [
            openseamap,
            nx_layer_ovl,
            // testLayer,
        ] : [
        ];

        var osm = new ol.layer.Tile({
            title: 'OpenStreetMap',
            source: new ol.source.OSM()
        });
        var esri_world = new ol.layer.Tile({
            title: 'ESRI World Imagery',
            source: esri.new_source('satellite')
        });
        var esri_street = new ol.layer.Tile({
            title: 'ESRI World Street Map',
            source: esri.new_source('street')
        });
        var watercolor = new ol.layer.Tile({
            title: 'Water color',
            source: new ol.source.Stamen({
                layer: 'watercolor',
                //~ url: 'http://tile.stamen.com/watercolor/{z}/{x}/{y}.jpg'
                url: '//stamen-tiles-{a-d}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg'
            })
        });
        var osm_base = new ol.layer.Tile({
            title: 'OSM base',
            source: new ol.source.OSM({
                crossOrigin: null,
                url: 'http://{a-c}.tiles.wmflabs.org/osm-no-labels/{z}/{x}/{y}.png'
            })
        });
        var no_background = new ol.layer.Vector({
            title: 'Plain background',
            source: new ol.source.Vector({
            })
        });

        var baseLayers =  standalone || this.params.pageFeatures ? [
            osm,
            esri_world,
            // esri_street,
            // osm_base,
            // no_background,
            watercolor,
        ] : [
            osm,
            esri_world,
            nx_layer,
        ];

        for (var i = 0; i < baseLayers.length; i++) {
            baseLayers[i].set('type', 'base');
            baseLayers[i].set('visible', false);
        }
        baseLayers[baseLayers.length-1].set('visible', true);

        var layers = [
            new ol.layer.Group({
                title: baselayersGroupName,
                layers: baseLayers
            })
        ];
        if (overLayers.length > 0 || this.params.pageFeatures)
            layers.push(new ol.layer.Group({
                    title: overlaysGroupName,
                    layers: overLayers
            }));

        var map = this.map = new ol.Map({
            target: chartlet_div,
            layers: layers,
            view: new ol.View({
                center: ol.proj.transform([this.params.lon, this.params.lat], 'EPSG:4326', 'EPSG:3857'),
                zoom: this.params.zoom
            }),
            interactions: ol.interaction.defaults(
                standalone ? {}
                : {
                    mouseWheelZoom:false,
                    // doubleClickZoom :false,
                }
            ),
            controls: ol.control.defaults({
                attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
                    collapsible: false
                })
            })
        });

        map.addControl(new ol.control.ScaleLine({
            units: 'nautical'
        }));

        loadWikiCss('CruisersWiki:Ol3-layerswitcher.css');
        loadWikiScript("CruisersWiki:Ol3-layerswitcher.js", function () {
            var layerSwitcher = new ol.control.LayerSwitcher({
                // tipLabel: 'Légende' // Optional label for button
            });
            map.addControl(layerSwitcher);
        });

        if (standalone) {
            this.params.page && this.loadFeatures();
            this.trackHash();
            this.addGraticule();
        } else if (this.params.pageFeatures) {
            this.loadFeatures();
        }
    };

    // add to a layer group
    ol3Chartlet.prototype.addNonBaseLayer = function (new_layer) {
        this.map.getLayers().forEach(
            function(layer) {
                if (layer.get('title') === overlaysGroupName) {
                    layer.getLayers().push(new_layer);
                }
            }
        );
    };

    ol3Chartlet.prototype.trackHash = function() {
        var doNotTrackHash = false;
        var setHashTimeoutID = null;

        var view = this.map.getView();
        var params = this.params;

        var onChangeCenterZoom = function () {
            var setHashDelay = 1000;

            var setHash = function () {
                var centre = view.getCenter();
                var lonlat = ol.proj.transform(centre, view.getProjection(), 'EPSG:4326');

                doNotTrackHash = true;
                setHashTimeoutID = null;

                params.lon = lonlat[0];
                params.lat = lonlat[1];
                params.zoom = view.getZoom();
                //console.log(center, zoom);

                location.hash = 'lat=' + round(params.lat) + '|lon=' + round(params.lon)
                    + '|zoom=' + params.zoom
                    + (params.layer ? '|layer=' + params.layer : '')
                    + (params.page ? '|page=' + params.page : '');
            };

            if (setHashTimeoutID) {
                window.clearTimeout(setHashTimeoutID);
            }
            setHashTimeoutID = window.setTimeout(setHash, setHashDelay);
        };

        view.on('change:center', onChangeCenterZoom);
        view.on('change:resolution', onChangeCenterZoom);

        window.addEventListener('hashchange',  function () {
            if (!location.hash || doNotTrackHash) {
                doNotTrackHash = false;
                return;
            }
            params = parseParams(location.hash.slice(1));
            if (params.lat != null && params.lon != null) {
                var centre = [params.lon, params.lat];
                view.setCenter(ol.proj.transform(centre, 'EPSG:4326', view.getProjection()))
                view.setZoom(params.zoom);
            }
        });
    };

    // Create the graticule
    ol3Chartlet.prototype.addGraticule = function () { // after http://map.openseamap.org/javascript/grid_wgs.js
        var this_ = this;
        loadWikiScript('CruisersWiki:Ol3chartlet/graticule.js', function () {
            var layer = graticuleLayer(this_.map);
            this_.addNonBaseLayer(layer);
        });
        /*
        var graticule = new ol.Graticule({
            map: this.map,
            // the style to use for the lines, optional.
            strokeStyle: new ol.style.Stroke({
                color: 'rgba(255,120,0,0.9)',
                width: 2,
                lineDash: [0.5, 4]
            })
        });
        // graticule.setMap(this.map);
        */
    };

    ol3Chartlet.prototype.loadFeatures = function (page) {
        loadWikiScript('CruisersWiki:Ol3chartlet features.js', function () {
            var layer = getArticleLayer(this.params);
            this.addNonBaseLayer(layer);
        }.bind(this));

        loadWikiCss('CruisersWiki:Ol3-popup.css');
        loadWikiScript("CruisersWiki:Ol3-popup.js", this.initPopups.bind(this));
    };

    ol3Chartlet.prototype.initPopups = function () {
        var map = this.map;

        var popup = new ol.Overlay.Popup();
        map.addOverlay(popup);

        var layerFilter = function (layer) {
            return ! layer.get('noclickable');
        };
        
        var popTemplate = 
            '<div class="cw-popup-name"><a href="{href}">{name}</a></div>\n' +
            '<div class="cw-popup-category">{category}</div>\n' +
            '<div class="cw-popup-content">{content}</div>';

        // display popup on click
        map.on('click', function(evt) {
            var feature = map.forEachFeatureAtPixel(
                evt.pixel,
                function(feature) {
                  return feature;
                },
                null,
                layerFilter
                );
            if (feature && ! feature.get('noclickable')) {
                var data = { 
                    href: feature.get("link"),
                    name: feature.get("name"),
                    category: feature.get("category"),
                    content: feature.get("description"),
                };
                popup.show(evt.coordinate, format(popTemplate, data));
            } else {
                popup.hide();
            }
        });

        // change mouse cursor when over marker
        map.on('pointermove', function(e) {
            //~ if (e.dragging) {
              //~ $(element).popover('destroy');
              //~ return;
            //~ }
            var pixel = map.getEventPixel(e.originalEvent);
            var hit = map.hasFeatureAtPixel(pixel, layerFilter);
            map.getTarget().style.cursor = hit ? 'pointer' : '';
        });
    };

    function dmsh2deg(dmsh) {
        var dmsFactors = [1, 60, 3600];
        var deg = 0;
        if (!dmsh)
            return deg;

        var parts = dmsh.split('_');
        for (var i=0, li = parts.length; i < li; i++) {
            var p = parts[i];
            if (isNaN(+ p)) {
                if (p == 'S' || p == 's' || p == 'W' || p == 'w')
                    deg = -deg;
                break;
            } else {
                deg += p / dmsFactors[i];
            }
        }
        return deg;
    }

    var zoomDelta = 0; // -3; // adjust zoom levels

    function parseParams(param_str) {
        var out = {
            icons: true,
            //recursive: 1,
            //childrenlocations: true,
            //captions: true,
        };

        var params = param_str.split('|');
        for (var i=0, li = params.length; i < li; i++) {
            var keyVal = params[i].split('=', 2);
            var key = $.trim(keyVal[0] || '').toLowerCase();
            var val = $.trim(keyVal[1] || '').toLowerCase();
            if (key == 'lon') {
                out.lon = dmsh2deg(val);
            } else if (key == 'lat') {
                out.lat = dmsh2deg(val);
            } else if (key == 'zoom') {
                out.zoom = +(val || 12) + zoomDelta;
            } else if (key == 'layer') {
                out.layer = val || 'N';
            } else if (key == 'page') {
                out.page = val;
            } else if (key == 'pagefeatures') {
                out.pageFeatures = !!val;
            } else if (key == 'captions') {
                out.captions = !!val;
            } else if (key == 'childrenlocations') {
                out.childrenlocations = true;
                out.recursive = 1;
            } else if (key == 'icons') {
                out.icons = !!val;
            }
        }
        return out;
    }

    function round(val) {
        var fact = 100000;
        return Math.round(val * fact) / fact;
    }

    function chartletStart(secondCall) {
        var $chartlets = $('.chartlet-test');
        if ($chartlets.length === 0) {
            return;
        }
        if (typeof ol === 'undefined') {
            if (!secondCall) { // try to load ol
                loadCss("http://cdnjs.cloudflare.com/ajax/libs/ol3/3.19.1/ol.css");
                loadWikiCss('CruisersWiki:Ol3chartlet.css');
                // use debug version, to allow patch below
                loadScript(
                    "http://cdnjs.cloudflare.com/ajax/libs/ol3/3.19.1/ol-debug.js", 
                    function () {
                        chartletStart(true);
                    }
                );
            }
        } else {
            // try to recover from /extensions/TreeAndMenu/dtree.js overwriting Node
            if (Node.ELEMENT_NODE === undefined) {
                if (document.firstElementChild.__proto__.ELEMENT_NODE == 1) {
                    Node = document.firstElementChild.__proto__;
                } else {
                    Node.ELEMENT_NODE = 1
                }
                ol.xml.isNode = function(value) {
                    //   return value instanceof Node;
                    return typeof value.nodeName === "string";
                };
            }            

            $chartlets.each( function () {
                new ol3Chartlet(this);
            });
        }
    };
    
    addOnloadHook(chartletStart);

})();
// 
Personal tools
advertisement
Friends of Cruisers Wiki