CruisersWiki:Ol3chartlet.js

From CruisersWiki

(Difference between revisions)
Jump to: navigation, search
Line 12: Line 12:
         return;
         return;
     }
     }
-
 
-
    var standalone_div = $('#ol3-chartlet-standalone')[0];
 
-
    var standalone = !! standalone_div;
 
     var nx = {
     var nx = {
Line 115: Line 112:
     };
     };
-
     function ol3Chartlet() {
+
    esri.new_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>'
 +
                })
 +
            ]
 +
        })
 +
    };
 +
 
 +
     function ol3Chartlet(chartlet_div) {
         console.log('ol3Chartlet');
         console.log('ol3Chartlet');
-
         var $chartlet = $(this);
+
 
-
        var params = parseParams(standalone && location.hash ? location.hash.slice(1) : $chartlet.text());
+
         this.params = parseParams(standalone && location.hash ? location.hash.slice(1) : $(chartlet_div).text());
         var iconFeature = new ol.Feature({
         var iconFeature = new ol.Feature({
Line 175: Line 187:
             title: 'ESRI World Imagery',
             title: 'ESRI World Imagery',
             type: 'base',
             type: 'base',
-
             source: new ol.source.TileArcGISRest({
+
             source: esri.new_source('satellite')
-
                url: esri.uris.satellite,
+
-
                params: {
+
-
                    FORMAT: 'JPG',
+
-
                    TRANSPARENT: false,
+
-
                },
+
-
                attributions: [
+
-
                    new ol.Attribution({
+
-
                        html: 'Tiles by ESRI <a href="' + esri.uris.satellite + '">Acknowledgements</a>'
+
-
                    })
+
-
                ]
+
-
            }),
+
         });
         });
Line 194: Line 195:
             });
             });
-
         var map = new ol.Map({
+
         this.map = new ol.Map({
-
             target: this,
+
             target: chartlet_div,
             layers: [
             layers: [
                 new ol.layer.Group({
                 new ol.layer.Group({
Line 201: Line 202:
                     layers: [
                     layers: [
                         new ol.layer.Tile({
                         new ol.layer.Tile({
-
                             title: 'OSM',
+
                             title: 'OpenStreetMap',
                             type: 'base',
                             type: 'base',
                             source: new ol.source.OSM()
                             source: new ol.source.OSM()
Line 251: Line 252:
         if (standalone) {
         if (standalone) {
-
             initStandalone (map, params);
+
             this.initStandalone();
         }
         }
     };
     };
-
     function initStandalone (map, params) {
+
     // add layer to a layer group
 +
    ol3Chartlet.prototype.addNonBaseLayer = function (new_layer) {
 +
        this.map.getLayers().forEach(
 +
            function(layer) {
 +
                if (layer.get('title') === 'Layers') {
 +
                    layer.getLayers().push(new_layer);
 +
                }
 +
            }
 +
        );
 +
    }
 +
 
 +
    ol3Chartlet.prototype.initStandalone = function () {
 +
 
 +
        var standalone = !! $('#ol3-chartlet-standalone')[0];
 +
        if (!standalone)
 +
            return;
 +
 
 +
        this.trackHash()
 +
        this.addCoordinateGrid();
 +
 
 +
        var page = this.params.page;
 +
        var _this = this;
 +
 
 +
        if (page) {
 +
            loadWikiScript('MediaWiki:GetKml.js', function () {
 +
                getKml(
 +
                    {
 +
                        page: page,
 +
                        decorated: true
 +
                    },
 +
                    _this.addPOIs.bind(_this)
 +
                );
 +
            });
 +
 
 +
            loadWikiCss('MediaWiki:Ol3-popup.css');
 +
            loadWikiScript("MediaWiki:Ol3-popup.js", _this.initPopups.bind(_this));
 +
        }
 +
    };
 +
    ol3Chartlet.prototype.trackHash = function() {
         var doNotTrackHash = false;
         var doNotTrackHash = false;
         var setHashTimeoutID = null;
         var setHashTimeoutID = null;
-
         var view = map.getView();
+
         var view = this.map.getView();
 +
        var params = this.params;
         var onChangeCenterZoom = function () {
         var onChangeCenterZoom = function () {
Line 277: Line 317:
                 //console.log(center, zoom);
                 //console.log(center, zoom);
-
                 location.hash= 'lat=' + round(params.lat) + '|lon=' + round(params.lon) + '|zoom=' + params.zoom
+
                 location.hash = 'lat=' + round(params.lat) + '|lon=' + round(params.lon)
 +
                    + '|zoom=' + params.zoom
                     + (params.layer ? '|layer=' + params.layer : '')
                     + (params.layer ? '|layer=' + params.layer : '')
                     + (params.page ? '|page=' + params.page : '');
                     + (params.page ? '|page=' + params.page : '');
Line 291: Line 332:
         view.on('change:resolution', onChangeCenterZoom);
         view.on('change:resolution', onChangeCenterZoom);
-
         var trackHash = function trackHash() {
+
         $(window).hashchange( function () {
             if (!location.hash || doNotTrackHash) {
             if (!location.hash || doNotTrackHash) {
                 doNotTrackHash = false;
                 doNotTrackHash = false;
Line 302: Line 343:
                 view.setZoom(params.zoom);
                 view.setZoom(params.zoom);
             }
             }
-
         };
+
         });
 +
    };
-
        window.onhashchange = trackHash;
+
    // add coordinate grid layer
 +
    ol3Chartlet.prototype.addCoordinateGrid = function () { // after http://map.openseamap.org/javascript/grid_wgs.js
 +
        var gridSteps = [
 +
            // in seconds
 +
            3 / 3600,        // 0.05'
 +
            6 / 3600, 12 / 3600, 30 / 3600,  // 0.1'  0.2'  0.5'
 +
            // in minutes
 +
            1 / 60, 2 / 60, 3 / 60, 5 / 60, 10 / 60, 20 / 60, 30 / 60,
 +
            // in degrees
 +
            1, 2, 3, 4, 6, 10, 15, 30, 45];
-
         function add_to_layers (new_layer) {
+
         var gridPixelStep = 100;
-
            // add to the proper layer group
+
-
            map.getLayers().forEach(
+
-
                function(layer) {
+
-
                    if (layer.get('title') === 'Layers') {
+
-
                        layer.getLayers().push(new_layer);
+
-
                    }
+
-
                }
+
-
            );
+
-
        }
+
-
         // load kml
+
         // Find matching grid step
-
         function add_kml_layer (kml) {
+
         var getGridStep = function (distance) {
-
             if (!kml)
+
             for (var i=0; i<gridSteps.length; i++) {
-
                return;
+
                 if (distance < gridSteps[i])
-
            // kml_uri='http://openlayers.org/en/v3.13.1/examples/data/kml/2012-02-10.kml';
+
                     return gridSteps[i];
-
            var format = new ol.format.KML({
+
             }
-
                showPointNames: false,
+
             return gridSteps[i-1];
-
            });
+
        };
-
            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
+
-
            add_to_layers(kml_layer);
+
-
        }
+
-
 
+
-
        //
+
-
        // add coordinate grid
+
-
        //
+
-
        function add_coord_grid () { // after http://map.openseamap.org/javascript/grid_wgs.js
+
-
 
+
-
            var gridSteps = [
+
-
                // in seconds
+
-
                3 / 3600,        // 0.05'
+
-
                6 / 3600, 12 / 3600, 30 / 3600,  // 0.1'  0.2'  0.5'
+
-
                // in minutes
+
-
                1 / 60, 2 / 60, 3 / 60, 5 / 60, 10 / 60, 20 / 60, 30 / 60,
+
-
                // in degrees
+
-
                1, 2, 3, 4, 6, 10, 15, 30, 45];
+
-
 
+
-
            var gridPixelStep = 100;
+
-
            // Find matching grid step
+
        // Format label
-
            var getGridStep = function (distance) {
+
        var zeroPad = function (x, int_places, dec, zero_pad) {
-
                for (var i=0; i<gridSteps.length; i++) {
+
            var pad = '                    ' // spaces there
-
                    if (distance < gridSteps[i])
+
            var sign = ''
-
                        return gridSteps[i];
+
            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 gridSteps[i-1];
+
            }
-
            };
+
            return sign + (pad + x.toFixed(dec)).slice(-places)
 +
        };
-
            // Format label
+
        var formatDegrees = function (deg, format, isLon) {
-
            var zeroPad = function (x, int_places, dec, zero_pad) {
+
            var adeg = Math.abs(deg);
-
                var pad = '                    ' // spaces there
+
            return ''
-
                var sign = ''
+
                 + zeroPad(Math.floor(adeg), isLon ? 3 : 2) + "°"
-
                 var places = dec > 0 ? int_places+dec+1 : int_places
+
                 + (format == 'd' ? '' : zeroPad((adeg * 60) % 60, 2) + "'")
-
                 if (zero_pad == null || zero_pad) {
+
                 + (isLon ? (deg < 0 ? 'W' : 'E') : (deg < 0 ? 'S' : 'N'));
-
                    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 view = this.map.getView();
-
                var adeg = Math.abs(deg);
+
-
                return ''
+
-
                    + zeroPad(Math.floor(adeg), isLon ? 3 : 2) + "°"
+
-
                    + (format == 'd' ? '' : zeroPad((adeg * 60) % 60, 2) + "'")
+
-
                    + (isLon ? (deg < 0 ? 'W' : 'E') : (deg < 0 ? 'S' : 'N'));
+
-
            };
+
-
            // layer loader
+
        // layer loader
-
            var loader = function(extent, resolution, projection) {
+
        var loader = function(extent, resolution, projection) {
-
                /**
+
            /**
-
                * @param {ol.Extent} extent Extent.
+
            * @param {ol.Extent} extent Extent.
-
                * @param {number} resolution Resolution.
+
            * @param {number} resolution Resolution.
-
                * @param {ol.proj.Projection} projection Projection.
+
            * @param {ol.proj.Projection} projection Projection.
-
                * @this {ol.source.Vector|ol.VectorTile}
+
            * @this {ol.source.Vector|ol.VectorTile}
-
                */
+
            */
-
                var view_proj = view.getProjection();
+
            var view_proj = view.getProjection();
-
                var geo_proj = 'EPSG:4326';
+
            var geo_proj = 'EPSG:4326';
-
                var lonlat_extent = ol.proj.transformExtent(extent, view_proj, geo_proj);
+
            var lonlat_extent = ol.proj.transformExtent(extent, view_proj, geo_proj);
-
                // clip extent to max values
+
            // clip extent to max values
-
                var x1 = Math.max (-180, lonlat_extent[0]);
+
            var x1 = Math.max (-180, lonlat_extent[0]);
-
                var x2 = Math.min ( 180, lonlat_extent[2]);
+
            var x2 = Math.min ( 180, lonlat_extent[2]);
-
                var y1 = Math.max ( -85, lonlat_extent[1]);
+
            var y1 = Math.max ( -85, lonlat_extent[1]);
-
                var y2 = Math.min (  85, lonlat_extent[3]);
+
            var y2 = Math.min (  85, lonlat_extent[3]);
-
                // grid step
+
            // grid step
-
                var step = getGridStep((lonlat_extent[3] - lonlat_extent[1]) / map.getSize()[1] * gridPixelStep);
+
            var step = getGridStep((lonlat_extent[3] - lonlat_extent[1]) / map.getSize()[1] * gridPixelStep);
-
                var labelFormat = step % 1 ? 'dm' : 'd'; //  round degrees number
+
            var labelFormat = step % 1 ? 'dm' : 'd'; //  round degrees number
-
                var features = [];
+
            var features = [];
-
                // line style
+
            // line style
-
                var strokeStyle = new ol.style.Stroke({
+
            var strokeStyle = new ol.style.Stroke({
-
                    color: [102, 102, 102, 255 * 0.8], // "#666666",
+
                color: [102, 102, 102, 255 * 0.8], // "#666666",
-
                    width: 1,
+
                width: 1,
-
                    //~ strokeOpacity: 0.8
+
                //~ strokeOpacity: 0.8
-
                });
+
            });
-
                // Vertical lines
+
            // Vertical lines
-
                for (var x = Math.ceil(x1 / step) * step + (x1 == -180 ? step : 0); x <= x2; x += step) {
+
            for (var x = Math.ceil(x1 / step) * step + (x1 == -180 ? step : 0); x <= x2; x += step) {
-
                    var l = new ol.geom.LineString([
+
                var l = new ol.geom.LineString([
-
                        ol.proj.transform([x, y1], geo_proj, view_proj),
+
                    ol.proj.transform([x, y1], geo_proj, view_proj),
-
                        ol.proj.transform([x, y2], geo_proj, view_proj)
+
                    ol.proj.transform([x, y2], geo_proj, view_proj)
-
                    ]);
+
                ]);
-
                    var f = new ol.Feature(l);
+
                var f = new ol.Feature(l);
-
                    f.setStyle(new ol.style.Style({
+
                f.setStyle(new ol.style.Style({
-
                        stroke: strokeStyle,
+
                    stroke: strokeStyle,
-
                        text: new ol.style.Text({
+
                    text: new ol.style.Text({
-
                            text: formatDegrees (x, labelFormat, true),
+
                        text: formatDegrees (x, labelFormat, true),
-
                            textAlign: 'end',
+
                        textAlign: 'end',
-
                            textBaseline: 'top',
+
                        textBaseline: 'top',
-
                            offsetX: 0,
+
                        offsetX: 0,
-
                            offsetY: - map.getSize()[1] / 2,
+
                        offsetY: - map.getSize()[1] / 2,
-
                            rotation: - Math.PI / 2,
+
                        rotation: - Math.PI / 2,
-
                            scale: 1.5,
+
                        scale: 1.5,
-
                            // labelAlign: "lt",
+
                        // labelAlign: "lt",
-
                        }),
+
                    }),
-
                    }));
+
                }));
-
                    f.set('auxiliary', true);
+
                f.set('auxiliary', true);
-
                    features.push (f);
+
                features.push (f);
-
                }
+
            }
-
                // Horizontal lines
+
            // Horizontal lines
-
                for (var y = Math.ceil(y1 / step) * step; y <= y2; y += step) {
+
            for (var y = Math.ceil(y1 / step) * step; y <= y2; y += step) {
-
                    var l = new ol.geom.LineString([
+
                var l = new ol.geom.LineString([
-
                        ol.proj.transform([x1, y], geo_proj, view_proj),
+
                    ol.proj.transform([x1, y], geo_proj, view_proj),
-
                        ol.proj.transform([x2, y], geo_proj, view_proj)
+
                    ol.proj.transform([x2, y], geo_proj, view_proj)
-
                    ]);
+
                ]);
-
                    var f = new ol.Feature(l);
+
                var f = new ol.Feature(l);
-
                    f.setStyle(new ol.style.Style({
+
                f.setStyle(new ol.style.Style({
-
                        stroke: strokeStyle,
+
                    stroke: strokeStyle,
-
                        text: new ol.style.Text({
+
                    text: new ol.style.Text({
-
                            text: formatDegrees (y, labelFormat, false),
+
                        text: formatDegrees (y, labelFormat, false),
-
                            textAlign: 'end',
+
                        textAlign: 'end',
-
                            textBaseline: 'top',
+
                        textBaseline: 'top',
-
                            offsetX: map.getSize()[0] / 2,
+
                        offsetX: map.getSize()[0] / 2,
-
                            offsetY: 0,
+
                        offsetY: 0,
-
                            rotation: 0,
+
                        rotation: 0,
-
                            scale: 1.5,
+
                        scale: 1.5,
-
                            //~ labelAlign: "lt",
+
                        //~ labelAlign: "lt",
-
                        }),
+
                    }),
-
                    }));
+
                }));
-
                    f.set('auxiliary', true);
+
                f.set('auxiliary', true);
-
                    features.push (f);
+
                features.push (f);
-
                }
+
            }
-
                this.addFeatures(features);
+
            this.addFeatures(features);
-
            };
+
        };
-
            var coord_grid = new ol.layer.Vector({
+
        var coord_grid = new ol.layer.Vector({
-
                title: 'Coordinate grid',
+
            title: 'Coordinate grid',
-
                visible: false,
+
            visible: false,
-
                source: new ol.source.Vector({
+
            source: new ol.source.Vector({
-
                    loader: loader,
+
                loader: loader,
-
                    strategy: ol.loadingstrategy.bbox
+
                strategy: ol.loadingstrategy.bbox
-
                })
+
            })
-
            });
+
        });
-
            // add to the proper layer group
+
        // add to the proper layer group
-
            add_to_layers (coord_grid);
+
        this.addNonBaseLayer(coord_grid);
-
            var onChangeCenterZoom = function () {
+
        var onChangeCenterZoom = function () {
-
                coord_grid.getSource().clear();
+
            coord_grid.getSource().clear();
-
            }
+
-
            view.on('change:center', onChangeCenterZoom);
+
-
            view.on('change:resolution', onChangeCenterZoom);
+
         }
         }
 +
        view.on('change:center', onChangeCenterZoom);
 +
        view.on('change:resolution', onChangeCenterZoom);
 +
    };
-
         add_coord_grid ();
+
    // load kml
 +
    ol3Chartlet.prototype.addPOIs = function(kml) {
 +
         if (!kml)
 +
            return;
 +
        // kml_uri='http://openlayers.org/en/v3.13.1/examples/data/kml/2012-02-10.kml';
 +
        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);
-
        function init_popups() {
+
             var features = format.readFeatures(
-
             var popup = new ol.Overlay.Popup();
+
                xml_tree,
-
             map.addOverlay(popup);
+
                {featureProjection: projection}
 +
             );
-
             // display popup on click
+
             this.addFeatures(features);
-
            map.on('click', function(evt) {
+
        };
-
                var feature = map.forEachFeatureAtPixel(evt.pixel,
+
        var kml_layer = new ol.layer.Vector({
-
                    function(feature) {
+
            title: 'POI',
-
                      return feature;
+
            visible:true,
-
                    });
+
            source: new ol.source.Vector({
-
                if (feature && ! feature.get('auxiliary')) {
+
                loader: loader,
-
                    popup.show(evt.coordinate,
+
            })
-
                        '<div class="cw-popup-name">' + feature.get("name") + '</div>' +
+
        });
-
                        '<div class="cw-popup-category">' + feature.get("styleUrl").split('#')[1] + '</div>' +
+
-
                        '<div class="cw-popup-content">' + feature.get("description") + '<div>'
+
-
                    );
+
-
                } else {
+
-
                    popup.hide();
+
-
                }
+
-
            });
+
-
            // change mouse cursor when over marker
+
        // add to the proper layer group
-
            map.on('pointermove', function(e) {
+
        this.addNonBaseLayer(kml_layer);
-
                //~ if (e.dragging) {
+
    };
-
                  //~ $(element).popover('destroy');
+
-
                  //~ return;
+
-
                //~ }
+
-
                var pixel = map.getEventPixel(e.originalEvent);
+
-
                var hit = map.hasFeatureAtPixel(pixel);
+
-
                map.getTarget().style.cursor = hit ? 'pointer' : '';
+
-
              });
+
-
        }
+
-
         if (params.page) {
+
    ol3Chartlet.prototype.initPopups = function () {
-
            loadWikiScript('MediaWiki:GetKml.js', function () {
+
         var map = this.map;
-
                 getKml(
+
 
-
                    {
+
        var popup = new ol.Overlay.Popup();
-
                        page: params.page,
+
        map.addOverlay(popup);
-
                        decorated: true
+
 
-
                     },
+
        // display popup on click
-
                     add_kml_layer
+
        map.on('click', function(evt) {
 +
            var feature = map.forEachFeatureAtPixel(evt.pixel,
 +
                 function(feature) {
 +
                  return feature;
 +
                });
 +
            if (feature && ! feature.get('auxiliary')) {
 +
                popup.show(evt.coordinate,
 +
                    '<div class="cw-popup-name">' + feature.get("name") + '</div>' +
 +
                     '<div class="cw-popup-category">' + feature.get("styleUrl").split('#')[1] + '</div>' +
 +
                     '<div class="cw-popup-content">' + feature.get("description") + '<div>'
                 );
                 );
-
             });
+
             } else {
 +
                popup.hide();
 +
            }
 +
        });
-
            loadWikiCss('MediaWiki:Ol3-popup.css');
+
        // change mouse cursor when over marker
-
             loadWikiScript("MediaWiki:Ol3-popup.js", init_popups);
+
        map.on('pointermove', function(e) {
-
         }
+
            //~ if (e.dragging) {
-
     }
+
              //~ $(element).popover('destroy');
 +
              //~ return;
 +
             //~ }
 +
            var pixel = map.getEventPixel(e.originalEvent);
 +
            var hit = map.hasFeatureAtPixel(pixel);
 +
            map.getTarget().style.cursor = hit ? 'pointer' : '';
 +
         });
 +
     };
     function dmsh2deg(dmsh) {
     function dmsh2deg(dmsh) {
Line 625: Line 637:
         };
         };
-
         $chartlets.each(ol3Chartlet);
+
         $chartlets.each( function () {
 +
            new ol3Chartlet(this);
 +
        });
     });
     });
});
});

Revision as of 10:33, 29 February 2016

/*

  ol3Chartlet.js
  Copyright (c) 2016 Vadim Shlyakhov
  Licensed MIT
  • /

addOnloadHook(function() {

   var $chartlets = $('.ol3-chartlet');
   if ($chartlets.length === 0) {
       return;
   }
   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: '© Navionics <a href="http://www.navionics.com/en/acknowledgements" target="_new" class="navionics-acknowledgements">Acknowledgements</a> | Not to be used for navigation',
   };
   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 {
           // 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;
                   callback();
               }
           });
       }
   };
   nx.formatTileUrl = function (options) { // sonar, overlay, depthUnit, safeDepth, showUGC
       options = options || {};
       sType = options.sonar ? 1 : 0;
       sAlpha = options.overlay ? 'TRUE' : 'FALSE';
       sUgc = options.showUGC ? 'TRUE' : 'FALSE';
       sDepthUnit = {
           'm': 1, 'metre': 1, 'meter': 1,
           'ft': 2, 'feet': 2,
           'fathom': 3,
       } [options.depthUnit] || 1;
       // sDepthLevel = (options.safeDepth || 10).toFixed(2);
       sDepthLevel = (options.safeDepth || 20).toFixed(0);
       params = $.param({
           LAYERS: 'config_' + sDepthUnit + '_' + sDepthLevel + '_' + sType,
           TRANSPARENT: sAlpha,
           UGC: sUgc,
           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",
       '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",
       'streets': "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': "http://server.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer",
       'national-geographic': "http://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer",
   };
   esri.new_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>'
               })
           ]
       })
   };
   function ol3Chartlet(chartlet_div) {
       console.log('ol3Chartlet');
       this.params = parseParams(standalone && location.hash ? location.hash.slice(1) : $(chartlet_div).text());
       var iconFeature = new ol.Feature({
           geometry: new ol.geom.Point(ol.proj.transform([params.lon, 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 iconLayer = 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',
           type: 'base',
           source: nx.new_source()
       });
       var nx_layer_ovl = new ol.layer.Tile({
           title: 'Navionics',
           // type: 'base',
           // visible: false,
           source: nx.new_source({overlay:true})
       });
       var esri_layer = new ol.layer.Tile({
           title: 'ESRI World Imagery',
           type: 'base',
           source: esri.new_source('satellite')
       });
       var view = new ol.View({
               center: ol.proj.transform([params.lon, params.lat], 'EPSG:4326', 'EPSG:3857'),
               zoom: params.zoom
           });
       this.map = new ol.Map({
           target: chartlet_div,
           layers: [
               new ol.layer.Group({
                   'title': 'Base',
                   layers: [
                       new ol.layer.Tile({
                           title: 'OpenStreetMap',
                           type: 'base',
                           source: new ol.source.OSM()
                       }),
                       esri_layer,
                       new ol.layer.Tile({
                           title: 'Water color',
                           type: 'base',
                           source: new ol.source.Stamen({
                               layer: 'watercolor'
                           })
                       }),
                       //~ new ol.layer.Vector({
                           //~ title: 'Plain background',
                           //~ type: 'base',
                           //~ source: new ol.source.Vector({
                           //~ })
                       //~ }),
                   ]
               }),
               new ol.layer.Group({
                   title: 'Layers',
                   layers: [
                       openseamap,
                       nx_layer_ovl,
                       // iconLayer,
                   ]
               })
           ],
           view: view,
           controls: ol.control.defaults({
               attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
                   collapsible: false
               })
           })
       });
       map.addControl(new ol.control.ScaleLine({
           units: 'nautical'
       }));
       loadWikiCss('MediaWiki:Ol3-layerswitcher.css');
       loadWikiScript("MediaWiki:Ol3-layerswitcher.js", function () {
           var layerSwitcher = new ol.control.LayerSwitcher({
               // tipLabel: 'Légende' // Optional label for button
           });
           map.addControl(layerSwitcher);
       });
       if (standalone) {
           this.initStandalone();
       }
   };
   // add layer to a layer group
   ol3Chartlet.prototype.addNonBaseLayer = function (new_layer) {
       this.map.getLayers().forEach(
           function(layer) {
               if (layer.get('title') === 'Layers') {
                   layer.getLayers().push(new_layer);
               }
           }
       );
   }
   ol3Chartlet.prototype.initStandalone = function () {
       var standalone = !! $('#ol3-chartlet-standalone')[0];
       if (!standalone)
           return;
       this.trackHash()
       this.addCoordinateGrid();
       var page = this.params.page;
       var _this = this;
       if (page) {
           loadWikiScript('MediaWiki:GetKml.js', function () {
               getKml(
                   {
                       page: page,
                       decorated: true
                   },
                   _this.addPOIs.bind(_this)
               );
           });
           loadWikiCss('MediaWiki:Ol3-popup.css');
           loadWikiScript("MediaWiki:Ol3-popup.js", _this.initPopups.bind(_this));
       }
   };
   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).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);
           }
       });
   };
   // add coordinate grid layer
   ol3Chartlet.prototype.addCoordinateGrid = function () { // after http://map.openseamap.org/javascript/grid_wgs.js
       var gridSteps = [
           // in seconds
           3 / 3600,        // 0.05'
           6 / 3600, 12 / 3600, 30 / 3600,  // 0.1'  0.2'  0.5'
           // in minutes
           1 / 60, 2 / 60, 3 / 60, 5 / 60, 10 / 60, 20 / 60, 30 / 60,
           // in degrees
           1, 2, 3, 4, 6, 10, 15, 30, 45];
       var gridPixelStep = 100;
       // Find matching grid step
       var getGridStep = function (distance) {
           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) + "'")
               + (isLon ? (deg < 0 ? 'W' : 'E') : (deg < 0 ? 'S' : 'N'));
       };
       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 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.getSize()[1] * gridPixelStep);
           var labelFormat = step % 1 ? '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.getSize()[1] / 2,
                       rotation: - Math.PI / 2,
                       scale: 1.5,
                       // labelAlign: "lt",
                   }),
               }));
               f.set('auxiliary', true);
               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.getSize()[0] / 2,
                       offsetY: 0,
                       rotation: 0,
                       scale: 1.5,
                       //~ labelAlign: "lt",
                   }),
               }));
               f.set('auxiliary', true);
               features.push (f);
           }
           this.addFeatures(features);
       };
       var coord_grid = new ol.layer.Vector({
           title: 'Coordinate grid',
           visible: false,
           source: new ol.source.Vector({
               loader: loader,
               strategy: ol.loadingstrategy.bbox
           })
       });
       // add to the proper layer group
       this.addNonBaseLayer(coord_grid);
       var onChangeCenterZoom = function () {
           coord_grid.getSource().clear();
       }
       view.on('change:center', onChangeCenterZoom);
       view.on('change:resolution', onChangeCenterZoom);
   };
   // load kml
   ol3Chartlet.prototype.addPOIs = function(kml) {
       if (!kml)
           return;
       // kml_uri='http://openlayers.org/en/v3.13.1/examples/data/kml/2012-02-10.kml';
       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
       this.addNonBaseLayer(kml_layer);
   };
   ol3Chartlet.prototype.initPopups = function () {
       var map = this.map;
       var popup = new ol.Overlay.Popup();
       map.addOverlay(popup);
       // display popup on click
       map.on('click', function(evt) {
           var feature = map.forEachFeatureAtPixel(evt.pixel,
               function(feature) {
                 return feature;
               });
           if (feature && ! feature.get('auxiliary')) {
               popup.show(evt.coordinate,
'
' + feature.get("name") + '
' + '
' + feature.get("styleUrl").split('#')[1] + '
' + '
' + feature.get("description") + '
'
               );
           } 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);
           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 = {};
       var params = param_str.split('|');
       for (var i=0, li = params.length; i < li; i++) {
           var keyVal = params[i].split('=', 2);
           var key = keyVal[0].replace(/^\s+|\s+$/g, ).toLowerCase();
           var val = keyVal[1].replace(/^\s+|\s+$/g, );
           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;
           }
       }
       return out;
   }
   function round(val) {
       var fact = 100000;
       return Math.round(val * fact) / fact;
   }
   // if (standalone && location.hash) {
   //     $('body').empty().append(standalone_div);
   //     $('body').addClass('cw-chartlet-extend');
   // }
   loadWikiCss('CruisersWiki:Ol3chartlet.css');
   loadCss("http://cdnjs.cloudflare.com/ajax/libs/ol3/3.13.1/ol.css");
   // use debug version, to allow patch below
   loadScript("http://cdnjs.cloudflare.com/ajax/libs/ol3/3.13.1/ol-debug.js", function () {
       if (typeof ol === 'undefined') {
           return;
       }
       // patch ol.xml as /extensions/TreeAndMenu/dtree.js overwrites Node
       ol.xml.isNode = goog.userAgent.IE ? ol.xml.isNodeIE_ : function(value) {
           //   return value instanceof Node;
           return typeof value.nodeName === "string";
       };
       $chartlets.each( function () {
           new ol3Chartlet(this);
       });
   });
});
Personal tools
advertisement
Friends of Cruisers Wiki