1 2// ðclass TileLayer.HERE 3// Tile layer for HERE maps tiles. 4L.TileLayer.HERE = L.TileLayer.extend({ 5 6 options: { 7 subdomains: '1234', 8 minZoom: 2, 9 maxZoom: 18, 10 11 // ðoption scheme: String = 'normal.day' 12 // The "map scheme", as documented in the HERE API. 13 scheme: 'normal.day', 14 15 // ðoption resource: String = 'maptile' 16 // The "map resource", as documented in the HERE API. 17 resource: 'maptile', 18 19 // ðoption mapId: String = 'newest' 20 // Version of the map tiles to be used, or a hash of an unique map 21 mapId: 'newest', 22 23 // ðoption format: String = 'png8' 24 // Image format to be used (`png8`, `png`, or `jpg`) 25 format: 'png8', 26 27 // ðoption appId: String = '' 28 // Required option. The `app_id` provided as part of the HERE credentials 29 appId: '', 30 31 // ðoption appCode: String = '' 32 // Required option. The `app_code` provided as part of the HERE credentials 33 appCode: '', 34 }, 35 36 37 initialize: function initialize(options) { 38 options = L.setOptions(this, options); 39 40 // Decide if this scheme uses the aerial servers or the basemap servers 41 var schemeStart = options.scheme.split('.')[0]; 42 options.tileResolution = 256; 43 44 if (L.Browser.retina) { 45 options.tileResolution = 512; 46 } 47 48// {Base URL}{Path}/{resource (tile type)}/{map id}/{scheme}/{zoom}/{column}/{row}/{size}/{format} 49// ?app_id={YOUR_APP_ID} 50// &app_code={YOUR_APP_CODE} 51// &{param}={value} 52 53 var path = '/{resource}/2.1/{resource}/{mapId}/{scheme}/{z}/{x}/{y}/{tileResolution}/{format}?app_id={appId}&app_code={appCode}'; 54 var attributionPath = '/maptile/2.1/copyright/{mapId}?app_id={appId}&app_code={appCode}'; 55 56 var tileServer = 'base.maps.api.here.com'; 57 if (schemeStart == 'satellite' || 58 schemeStart == 'terrain' || 59 schemeStart == 'hybrid') { 60 tileServer = 'aerial.maps.api.here.com'; 61 } 62 if (options.scheme.indexOf('.traffic.') !== -1) { 63 tileServer = 'traffic.maps.api.here.com'; 64 } 65 66 var tileUrl = 'https://{s}.' + tileServer + path; 67 68 this._attributionUrl = L.Util.template('https://1.' + tileServer + attributionPath, this.options); 69 70 L.TileLayer.prototype.initialize.call(this, tileUrl, options); 71 72 this._attributionText = ''; 73 74 }, 75 76 onAdd: function onAdd(map) { 77 L.TileLayer.prototype.onAdd.call(this, map); 78 79 if (!this._attributionBBoxes) { 80 this._fetchAttributionBBoxes(); 81 } 82 }, 83 84 onRemove: function onRemove(map) { 85 L.TileLayer.prototype.onRemove.call(this, map); 86 87 this._map.attributionControl.removeAttribution(this._attributionText); 88 89 this._map.off('moveend zoomend resetview', this._findCopyrightBBox, this); 90 }, 91 92 _fetchAttributionBBoxes: function _onMapMove() { 93 var xmlhttp = new XMLHttpRequest(); 94 xmlhttp.onreadystatechange = L.bind(function(){ 95 if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 96 this._parseAttributionBBoxes(JSON.parse(xmlhttp.responseText)); 97 } 98 }, this); 99 xmlhttp.open("GET", this._attributionUrl, true); 100 xmlhttp.send(); 101 }, 102 103 _parseAttributionBBoxes: function _parseAttributionBBoxes(json) { 104 if (!this._map) { return; } 105 var providers = json[this.options.scheme.split('.')[0]] || json.normal; 106 for (var i=0; i<providers.length; i++) { 107 if (providers[i].boxes) { 108 for (var j=0; j<providers[i].boxes.length; j++) { 109 var box = providers[i].boxes[j]; 110 providers[i].boxes[j] = L.latLngBounds( [ [box[0], box[1]], [box[2], box[3]] ]); 111 } 112 } 113 } 114 115 this._map.on('moveend zoomend resetview', this._findCopyrightBBox, this); 116 117 this._attributionProviders = providers; 118 119 this._findCopyrightBBox(); 120 }, 121 122 _findCopyrightBBox: function _findCopyrightBBox() { 123 if (!this._map) { return; } 124 var providers = this._attributionProviders; 125 var visibleProviders = []; 126 var zoom = this._map.getZoom(); 127 var visibleBounds = this._map.getBounds(); 128 129 for (var i=0; i<providers.length; i++) { 130 if (providers[i].minLevel < zoom && providers[i].maxLevel > zoom) 131 132 if (!providers[i].boxes) { 133 // No boxes = attribution always visible 134 visibleProviders.push(providers[i]); 135 break; 136 } 137 138 for (var j=0; j<providers[i].boxes.length; j++) { 139 var box = providers[i].boxes[j]; 140 if (visibleBounds.overlaps(box)) { 141 visibleProviders.push(providers[i]); 142 break; 143 } 144 } 145 } 146 147 var attributions = ['<a href="https://legal.here.com/terms/serviceterms/gb/">HERE maps</a>']; 148 for (var i=0; i<visibleProviders.length; i++) { 149 var provider = visibleProviders[i]; 150 attributions.push('<abbr title="' + provider.alt + '">' + provider.label + '</abbr>'); 151 } 152 153 var attributionText = '© ' + attributions.join(', ') + '. '; 154 155 if (attributionText !== this._attributionText) { 156 this._map.attributionControl.removeAttribution(this._attributionText); 157 this._map.attributionControl.addAttribution(this._attributionText = attributionText); 158 } 159 }, 160 161}); 162 163 164L.tileLayer.here = function(opts){ 165 return new L.TileLayer.HERE(opts); 166}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.