nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

commit 5897c861e1eed55b3efc6f350c73a7a9de402590
parent 199d71b4223e0e051abbdf25b50396c9f66f2b64
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Tue, 31 Jan 2017 00:03:12 +0300

[wikimapia] use new loader module

Diffstat:
Msrc/layers.js | 15++++++++-------
Asrc/lib/leaflet.layer.wikimapia/index.js | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/leaflet.layer.wikimapia/style.css | 13+++++++++++--
Asrc/lib/leaflet.layer.wikimapia/wikimapia-loader.js | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/lib/leaflet.layer.wikimapia/wikimapia.js | 313-------------------------------------------------------------------------------
Msrc/lib/leaflet.layer.wikimapia/wm-utils.js | 113++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Msrc/lib/tiled-data-loader/index.js | 6+++---
7 files changed, 393 insertions(+), 355 deletions(-)

diff --git a/src/layers.js b/src/layers.js @@ -7,6 +7,7 @@ import 'lib/leaflet.layer.soviet-topomaps-grid'; import 'lib/leaflet.layer.westraPasses'; import 'lib/leaflet.layer.nordeskart'; import 'lib/leaflet.layer.tracks-collection'; +import 'lib/leaflet.layer.wikimapia'; export default function getLayers() { const layers = [ @@ -195,13 +196,13 @@ export default function getLayers() { isDefault: true, layer: new L.Layer.SovietTopoGrid({code: 'Ng'}) }, - // { - // title: 'Wikimapia', - // order: 1130, - // isOverlay: true, - // isDefault: true, - // layer: new L.Wikimapia({code: 'W', zIndexOffset: 10000}), - // }, + { + title: 'Wikimapia', + order: 1130, + isOverlay: true, + isDefault: true, + layer: new L.Wikimapia({code: 'W'}), + }, { title: 'Mountain passes (Westra)', order: 1140, diff --git a/src/lib/leaflet.layer.wikimapia/index.js b/src/lib/leaflet.layer.wikimapia/index.js @@ -0,0 +1,207 @@ +import L from 'leaflet'; +import {WikimapiaLoader} from './wikimapia-loader'; +import './style.css'; + + +function isPointInPolygon(polygon, p) { + var inside = false; + var prevNode = polygon[polygon.length - 1], + node, i; + for (i = 0; i < polygon.length; i++) { + node = polygon[i]; + if ( + ((node[0] <= p[0] && p[0] < prevNode[0]) || prevNode[0] <= p[0] && p[0] < node[0]) && + p[1] < (prevNode[1] - node[1]) * (p[0] - node[0]) / (prevNode[0] - node[0]) + node[1] + ) { + inside = !inside; + } + prevNode = node; + } + return inside; +} + +L.Wikimapia = L.GridLayer.extend({ + options: { + tileSize: 1024, + updateWhenIdle: true, + }, + + initialize: function(options) { + L.GridLayer.prototype.initialize.call(this, options); + this.loader = null; + }, + + onAdd: function(map) { + if (!this.loader) { + this.loader = new WikimapiaLoader(map.project.bind(map)); + } + L.GridLayer.prototype.onAdd.call(this, map); + this.on('tileunload', this.onTileUnload, this); + map.on('mousemove', this.onMouseMove, this); + map.on('click', this.onClick, this); + }, + + onRemove: function(map) { + map.off('mousemove', this.onMouseMove, this); + map.off('click', this.onClick, this); + if (this.highlightedPlace) { + this._map.removeLayer(this.highlightedPlace.polygon); + this._map.removeLayer(this.highlightedPlace.label); + this.highlightedPlace = null; + } + L.TileLayer.prototype.onRemove.call(this, map); + this.off('tileunload', this.onTileUnload, this); + + }, + + drawTile: function(canvas) { + if (!this._map) { + return; + } + const + tileData = canvas._tileData, + adjustment = canvas._adjustment; + if (!tileData) { + return; + } + + const canvasCtx = canvas.getContext('2d'); + canvasCtx.beginPath(); + canvasCtx.strokeStyle = '#CFA600'; + canvasCtx.lineWidth = 1; + for (let place of tileData.places) { + let polygon = place.localPolygon; + if (!polygon) { + continue; + } + if (adjustment) { + let {multiplier, offsetX, offsetY} = adjustment, + polygon2 = []; + for (let i = 0; i < polygon.length; i++) { + let p = polygon[i]; + polygon2.push({ + x: p.x * multiplier - offsetX, + y: p.y * multiplier - offsetY + } + ); + } + polygon = polygon2; + } + canvasCtx.moveTo(polygon[0].x, polygon[0].y); + let p; + for (let i = 1; i < polygon.length; i++) { + p = polygon[i]; + canvasCtx.lineTo(p.x, p.y); + } + canvasCtx.lineTo(polygon[0].x, polygon[0].y); + } + canvasCtx.stroke(); + + }, + + createTile: function(coords, done) { + const canvas = L.DomUtil.create('canvas', 'leaflet-tile'); + canvas.width = this.options.tileSize; + canvas.height = this.options.tileSize; + + let {dataPromise, abortLoading} = this.loader.requestTileData(coords); + dataPromise.then((data) => { + canvas._tileData = data.tileData; + canvas._adjustment = data.adjustment; + this.drawTile(canvas); + this._tileOnLoad(done, canvas) + } + ); + + canvas._abortLoading = abortLoading; + return canvas; + }, + + _tileOnLoad: function(done, tile) { + // For https://github.com/Leaflet/Leaflet/issues/3332 + if (L.Browser.ielt9) { + setTimeout(L.bind(done, this, null, tile), 0); + } else { + done(null, tile); + } + }, + + onTileUnload: function(e) { + const tile = e.tile; + tile._abortLoading(); + delete tile._tileData; + delete tile._adjustment; + }, + + _tileCoordsFromEvent: function(e) { + const layerPoint = this._map.getPixelOrigin().add(e.layerPoint); + const tileSize = this.options.tileSize; + let coords = { + x: Math.floor(layerPoint.x / tileSize), + y: Math.floor(layerPoint.y / tileSize), + z: this._map.getZoom() + }; + + return coords; + }, + + getPlaceAtMousePos: function(e) { + const tileCoords = this._tileCoordsFromEvent(e); + let tile = this._tiles[this._tileCoordsToKey(tileCoords)]; + if (!tile) { + return null; + } + const tileData = tile.el._tileData; + if (!tileData) { + return null; + } + return this.getPlaceAtLatlng(e.latlng, tileData.places); + }, + + onMouseMove: function(e) { + const place = this.getPlaceAtMousePos(e); + if (this.highlightedPlace && (!place || this.highlightedPlace.id != place.id)) { + this._map.removeLayer(this.highlightedPlace.polygon); + this._map.removeLayer(this.highlightedPlace.label); + this.highlightedPlace = null; + } + + if (place && !this.highlightedPlace) { + this.highlightedPlace = { + id: place.id, + polygon: L.polygon(place.polygon, { + weight: 0, + color: '#E6B800' + } + ), + label: L.tooltip({className: 'wikimapia-tooltip'}, null) + }; + this.highlightedPlace.label.setLatLng(e.latlng); + this.highlightedPlace.polygon.addTo(this._map); + this.highlightedPlace.label.setContent(place.title); + this._map.addLayer(this.highlightedPlace.label); + } + if (this.highlightedPlace) { + this.highlightedPlace.label.setLatLng(e.latlng); + } + }, + + onClick: function(e) { + + }, + + getPlaceAtLatlng: function(latlng, places) { + let {lat, lng} = latlng, + bounds, place; + for (let i = places.length - 1; i >= 0; i--) { + place = places[i]; + bounds = place.boundsWESN; + if (lng >= bounds[0] && lng <= bounds[1] && lat >= bounds[2] && lat <= bounds[3] && + isPointInPolygon(place.polygon, [lat, lng])) { + return place; + } + } + } + + } +); diff --git a/src/lib/leaflet.layer.wikimapia/style.css b/src/lib/leaflet.layer.wikimapia/style.css @@ -10,4 +10,14 @@ z-index: 10000; max-width: 500px; box-sizing: border-box; -} -\ No newline at end of file + margin-top: -6px; + /*box-shadow: none !important;*/ +} + +.wikimapia-tooltip:before { + border: none !important; +} + +.leaflet-tooltip-right { + margin-left: 16px !important; +} diff --git a/src/lib/leaflet.layer.wikimapia/wikimapia-loader.js b/src/lib/leaflet.layer.wikimapia/wikimapia-loader.js @@ -0,0 +1,80 @@ +import {TiledDataLoader} from 'lib/tiled-data-loader'; +import wmUtils from './wm-utils' +import urlViaCorsProxy from 'lib/CORSProxy'; + +class WikimapiaLoader extends TiledDataLoader { + maxZoom = 15; + tileSize = 1024; + + constructor(projectFunc) { + super(); + this._project = projectFunc; + + } + + getFromCache(dataTileCoords) { + dataTileCoords = Object.assign({}, dataTileCoords); + let exactMatch = true; + while (dataTileCoords.z >= 0) { + let key = this.makeTileKey(dataTileCoords); + let res = this._cache.get(key); + if (res.found) { + if (exactMatch || !res.value.hasChildren) { + res['coords'] = dataTileCoords; + return res; + } + break; + } + dataTileCoords.z -= 1; + dataTileCoords.x = Math.floor(dataTileCoords.x / 2); + dataTileCoords.y = Math.floor(dataTileCoords.y / 2); + exactMatch = false; + } + return {found: false}; + } + + layerTileToDataTileCoords(layerTileCoords) { + let z = layerTileCoords.z - 2; + if (z > this.maxZoom) { + let z2 = this.maxZoom, + multiplier = 1 << (z - z2); + return { + x: Math.floor(layerTileCoords.x / multiplier), + y: Math.floor(layerTileCoords.y / multiplier), + z: z2 + } + } else { + return {z, x: layerTileCoords.x, y: layerTileCoords.y} + } + } + + makeRequestData(dataTileCoords) { + let url = wmUtils.makeTileUrl(dataTileCoords); + url = urlViaCorsProxy(url); + return { + url, + options: {timeout: 20000} + } + } + + processResponse(xhr) { + const tileData = wmUtils.parseTile(xhr.response, this._project); + return { + tileData, + coords: tileData.coords + } + } + + calcAdjustment(layerTileCoords, dataTileCoords) { + const adjustment = super.calcAdjustment( + {x: layerTileCoords.x, y: layerTileCoords.y, z: layerTileCoords.z - 2}, + dataTileCoords); + if (adjustment) { + adjustment.offsetX *= 1024; + adjustment.offsetY *= 1024; + } + return adjustment; + } +} + +export {WikimapiaLoader}; +\ No newline at end of file diff --git a/src/lib/leaflet.layer.wikimapia/wikimapia.js b/src/lib/leaflet.layer.wikimapia/wikimapia.js @@ -1,313 +0,0 @@ -import L from 'leaflet'; -import wmUtils from './wm-utils'; - - -function isPointInPolygon(polygon, p) { - var inside = false; - var prevNode = polygon[polygon.length - 1], - node, i; - for (i = 0; i < polygon.length; i++) { - node = polygon[i]; - if ((node[0] <= p[0] && p[0] < prevNode[0] || prevNode[0] <= p[0] && p[0] < node[0]) && p[1] < (prevNode[1] - node[1]) * (p[0] - node[0]) / (prevNode[0] - node[0]) + node[1]) { - inside = !inside; - } - prevNode = node; - } - return inside; -} - -const Label = L.Class.extend({ - initialize: function(text, latlng) { - this.text = text; - this.latlng = latlng; - }, - - onAdd: function(map) { - this._map = map; - this._container = L.DomUtil.create('div', 'leaflet-marker-icon leaflet-zoom-animated wikimapia-tooltip'); - this._container.innerHTML = this.text; - - map._container.appendChild(this._container); - map.on('viewreset', this._updatePosition, this); - map.on('mousemove', this.onMouseMove, this); - this._updatePosition(); - }, - - onRemove: function(map) { - map.off('viewreset', this._updatePosition, this); - map.off('mousemove', this.onMouseMove, this); - map._container.removeChild(this._container); - }, - - onMouseMove: function(e) { - this.latlng = e.latlng; - this._updatePosition(); - }, - - _updatePosition: function() { - var pos = this._map.latLngToContainerPoint(this.latlng); - var right = pos.x + this._container.clientWidth + 16 + 2; - var x, y; - y = pos.y - 16; - x = pos.x; - if (right > this._map._container.clientWidth) { - x -= this._container.clientWidth + 16 + 2; - } else { - x += 16; - } - L.Util.extend(this._container.style, { - top: y + 'px', - left: x + 'px' - } - ); - } - } -); - -// TODO: как-то посылать remove() в очередь загрузок при событии tileunload -L.Layer.Wikimapia = L.GridLayer.extend({ - options: { - tileSize: 512, - updateWhenIdle: true, - cacheSize: 30 - }, - - initialize: function(options) { - L.GridLayer.prototype.initialize.call(this, options); - this._cache = {}; - this._cachePriority = []; - this._downloading = {}; - }, - - onAdd: function(map) { - L.GridLayer.prototype.onAdd.call(this, map); - map.on('mousemove', this.highlightPlace, this); - // map.on('click', this.showPlaceDetails, this); - }, - - onRemove: function(map) { - map.off('mousemove', this.highlightPlace, this); - // map.off('click', this.showPlaceDetails, this); - // if (this.highlightedPlace) { - // this._map.removeLayer(this.highlightedPlace.polygon); - // this._map.removeLayer(this.highlightedPlace.label); - // this.highlightedPlace = null; - // } - L.TileLayer.prototype.onRemove.call(this, map); - - }, - - raiseCachePriority: function(tileId) { - const i = this._cachePriority.indexOf(tileId); - if (i > -1) { - this._cachePriority.splice(i, 1); - } - this._cachePriority.unshift(tileId); - }, - - getWikimapiaDataFromCache: function(tileId) { - console.log('getWikimapiaDataFromCache', tileId); - if (tileId in this._cache) { - console.log('Cache hit', tileId); - this.raiseCachePriority(tileId); - return this._cache[tileId]; - } - while (tileId.length > 1) { - tileId = tileId.substr(0, tileId.length - 1); - let tile = this._cache[tileId]; - if (tile && !tile.hasChildren) { - console.log('Cache hit (parent)', tileId); - this.raiseCachePriority(tileId); - return tile; - } - } - console.log('Cache miss', tileId); - return null; - }, - - putWikimapiaDataToCache: function(data) { - const tileId = data.tileId; - console.log('putWikimapiaDataToCache', tileId); - this._cache[tileId] = data; - this.raiseCachePriority(tileId); - while (this._cachePriority.length > this.options.cacheSize) { - let tileId = this._cachePriority.pop(); - delete this._cache[tileId]; - } - }, - - // TODO: каждые 50-100 мс отдавать управление - projectPlacesForZoom: function(tile, viewZoom) { - if (viewZoom < tile.coords.z) { - throw new Error('viewZoom < tile.zoom'); - } - if (tile.places && tile.places[0] && tile.places[0].projectedPolygons && - tile.places[0].projectedPolygons[viewZoom]) { - return; - } - const virtualTileSize = 256 * (2 ** (viewZoom - tile.coords.z)); - const p1 = L.point([tile.coords.x * virtualTileSize, tile.coords.y * virtualTileSize]), - p2 = L.point([(tile.coords.x + 1) * virtualTileSize, (tile.coords.y + 1) * virtualTileSize]), - latlng1 = this._map.unproject(p1, viewZoom), - latlng2 = this._map.unproject(p2, viewZoom), - lat0 = latlng1.lat, - lng0 = latlng1.lng; - const qx = (p2.x - p1.x) / (latlng2.lng - latlng1.lng), - qy = (p2.y - p1.y) / (latlng2.lat - latlng1.lat); - - const offsets = [], - offsetsStep = virtualTileSize / 64; - const y0 = p1.y; - for (let y = -virtualTileSize; y <= 2 * virtualTileSize; y += offsetsStep) { - let lat = y / qy + lat0; - let offset = this._map.project([lat, lng0], viewZoom).y - y0 - y; - offsets.push(offset); - } - - let ll, offset, offsetPos, offsetIndex, offsetIndexDelta, x, y; - const x0 = p1.x; - for (let place of tile.places) { - let polygon = place.polygon; - if (polygon.length < 3) { - continue; - } - let projectedPolygon = []; - for (let i = 0; i < polygon.length; i++) { - ll = polygon[i]; - x = (ll[1] - lng0) * qx; - y = (ll[0] - lat0) * qy; - offsetPos = (y + virtualTileSize) / offsetsStep; - offsetIndex = Math.floor(offsetPos); - offsetIndexDelta = offsetPos - offsetIndex; - offset = offsets[offsetIndex] * (1 - offsetIndexDelta) + offsets[offsetIndex + 1] * offsetIndexDelta; - projectedPolygon.push([x + x0, y + offset + y0]); - } - projectedPolygon = projectedPolygon.map(L.point); - projectedPolygon = L.LineUtil.simplify(projectedPolygon, 1.5); - if (!place.projectedPolygons) { - place.projectedPolygons = []; - } - place.projectedPolygons[viewZoom] = projectedPolygon; - } - }, - - getWikimapiaDataFromServer: async function(tileId) { - console.log('getWikimapiaDataFromServer', tileId); - let tile; - - try { - tile = await wmUtils.fetchTile(tileId) - } catch (e) { - return {error: e.message}; - } finally { - delete this._downloading[tileId]; - } - try { - tile = wmUtils.parseTile(tile) - } catch (e) { - console.log('Error parsing tile', e); - return {'error': `Malformed wikimapia data for tile ${tileId}`} - } - - this.putWikimapiaDataToCache(tile); - return tile; - }, - - getWikimapiaDataForTile: function(coords) { - console.log('getWikimapiaDataForTile', coords); - coords = wmUtils.getWikimapiaTileCoords(coords, this.options.tileSize); - const tileId = wmUtils.getTileId(coords); - if (tileId in this._downloading) { - console.log('Already downloading', coords, tileId); - return this._downloading[tileId]; - } - let data = this.getWikimapiaDataFromCache(tileId); - if (data) { - return Promise.resolve(data); - } - let dataPromise = this.getWikimapiaDataFromServer(tileId); - this._downloading[tileId] = dataPromise; - return dataPromise; - }, - - - drawTile: function(coords, canvas, data) { - if (!this._map) { - return; - } - console.log('drawTile', coords, data); - if (!data.places) { - return; - } - const canvasCtx = canvas.getContext('2d'); - canvasCtx.strokeStyle = '#CFA600'; - canvasCtx.lineWidth = 1; - this.projectPlacesForZoom(data, coords.z); - const x0 = coords.x * this.options.tileSize, - y0 = coords.y * this.options.tileSize; - for (let place of data.places) { - if (!place.projectedPolygons) { - continue; - } - let polygon = place.projectedPolygons[coords.z]; - canvasCtx.moveTo(polygon[0].x - x0, polygon[0].y - y0); - let p; - for (let i = 1; i < polygon.length; i++) { - p = polygon[i]; - canvasCtx.lineTo(p.x - x0, p.y - y0); - } - canvasCtx.lineTo(polygon[0].x - x0, polygon[0].y - y0); - } - canvasCtx.stroke(); - - }, - - createTile: function(coords, done) { - console.log('createTile', coords); - const canvas = L.DomUtil.create('canvas', 'leaflet-tile'); - canvas.width = this.options.tileSize; - canvas.height = this.options.tileSize; - this.getWikimapiaDataForTile(coords) - .then((data) => { - let t1 = Date.now(); - this.drawTile(coords, canvas, data) - let t2 = Date.now(); - console.log('Tile drawn', t2 - t1); - } - ) - .then(() => { - done(null, canvas) - } - ); - return canvas; - }, - - getTileAtLayerPoint: function(x, y, z) { - for (let tileId of this._cachePriority) { - let tile = this._cache[tileId]; - - } - // var i, tile; - - // for (i = 0; i < this.tileCache.length; i++) { - // tile = this.tileCache[i]; - // if (x >= tile.x0 && x < tile.x0 + 1024 && y >= tile.y0 && y < tile.y0 + 1024) { - // return tile; - // } - // } - }, - - getPlaceAtLayerPoint: function(x, y, places) { - var j, bounds, place; - for (j = places.length - 1; j >= 0; j--) { - place = places[j]; - bounds = place.localBoundsWESN; - if (x >= bounds[0] && x <= bounds[1] && y >= bounds[3] && y <= bounds[2] && isPointInPolygon(place.localPolygon, [x, y])) { - return place; - } - } - } - - - } -); diff --git a/src/lib/leaflet.layer.wikimapia/wm-utils.js b/src/lib/leaflet.layer.wikimapia/wm-utils.js @@ -1,7 +1,3 @@ -import urlViaCorsProxy from 'lib/CORSProxy'; -import 'lib/xhr-promise'; - - // (1233,130,5) -> "032203" function getTileId({x, y, z}) { let id = []; @@ -16,6 +12,12 @@ function getTileId({x, y, z}) { return id.reverse().join(''); } +function makeTileUrl(coords) { + const + tileId = getTileId(coords), + urlPath = tileId.replace(/(\d{3})(?!$)/g, '$1/'); // "033331022" -> "033/331/022" + return `http://wikimapia.org/z1/itiles/${urlPath}.xy?342342`; +} function tileIdToCoords(tileId) { const z = tileId.length - 1; @@ -46,29 +48,6 @@ function getWikimapiaTileCoords(coords, viewTileSize) { return {x, y, z}; } -function fetchTile(tileId) { - let url = tileId.replace(/(\d{3})(?!$)/g, '$1/'); // "033331022" -> "033/331/022" - url = 'http://wikimapia.org/z1/itiles/' + url + '.xy?342342'; - - url = urlViaCorsProxy(url); - let {promise, requestId} = window.xmlHttpRequestQueue.put(url, {timeout: 30000}); - promise = promise.then((xhr) => { - if (xhr.status === 0) { - throw new Error(`Network error while fetching wikimapia data, request "${url}"`); - } - if (xhr.status !== 200) { - throw new Error(`Wikimapia server responded with status ${xhr.status}, request "${url}"`); - } - return xhr.response; - } - ); - const abort = () => { - window.xmlHttpRequestQueue.remove(requestId); - }; - // return {promise, abort}; - return promise; - -} function decodeTitles(s) { const titles = {}; @@ -120,7 +99,23 @@ function decodePolygon(s) { return coords; } -function parseTile(s) { +function makeCoordsLocal(line, tileCoords, projectFunc) { + const {x: tileX, y: tileY, z: tileZ} = tileCoords, + x0 = tileX * 1024, + y0 = tileY * 1024, + localCoords = []; + let latlon, p; + for (let i = 0; i < line.length; i++) { + latlon = line[i]; + p = projectFunc(latlon, tileZ + 2); + p.x -= x0; + p.y -= y0; + localCoords.push(p); + } + return localCoords; +} + +function parseTile(s, projectFunc) { const tile = {}; const places = tile.places = []; const lines = s.split('\n'); @@ -170,9 +165,67 @@ function parseTile(s) { throw new Error(`Polygon has ${coords.length} points`); } place.polygon = coords; + place.localPolygon = makeCoordsLocal(coords, tile.coords, projectFunc); + // place.localBoundsWESN = makeBoundsLocal(place.boundsWESN); places.push(place); } return tile; } -export default {getTileId, getWikimapiaTileCoords, fetchTile, parseTile} -\ No newline at end of file +// быстрое проектирование полигонов +// TODO: каждые 50-100 мс отдавать управление +// projectPlacesForZoom: function(tile, viewZoom) { +// if (viewZoom < tile.coords.z) { +// throw new Error('viewZoom < tile.zoom'); +// } +// if (tile.places && tile.places[0] && tile.places[0].projectedPolygons && +// tile.places[0].projectedPolygons[viewZoom]) { +// return; +// } +// const virtualTileSize = 256 * (2 ** (viewZoom - tile.coords.z)); +// const p1 = L.point([tile.coords.x * virtualTileSize, tile.coords.y * virtualTileSize]), +// p2 = L.point([(tile.coords.x + 1) * virtualTileSize, (tile.coords.y + 1) * virtualTileSize]), +// latlng1 = this._map.unproject(p1, viewZoom), +// latlng2 = this._map.unproject(p2, viewZoom), +// lat0 = latlng1.lat, +// lng0 = latlng1.lng; +// const qx = (p2.x - p1.x) / (latlng2.lng - latlng1.lng), +// qy = (p2.y - p1.y) / (latlng2.lat - latlng1.lat); +// +// const offsets = [], +// offsetsStep = virtualTileSize / 64; +// const y0 = p1.y; +// for (let y = -virtualTileSize; y <= 2 * virtualTileSize; y += offsetsStep) { +// let lat = y / qy + lat0; +// let offset = this._map.project([lat, lng0], viewZoom).y - y0 - y; +// offsets.push(offset); +// } +// +// let ll, offset, offsetPos, offsetIndex, offsetIndexDelta, x, y; +// const x0 = p1.x; +// for (let place of tile.places) { +// let polygon = place.polygon; +// if (polygon.length < 3) { +// continue; +// } +// let projectedPolygon = []; +// for (let i = 0; i < polygon.length; i++) { +// ll = polygon[i]; +// x = (ll[1] - lng0) * qx; +// y = (ll[0] - lat0) * qy; +// offsetPos = (y + virtualTileSize) / offsetsStep; +// offsetIndex = Math.floor(offsetPos); +// offsetIndexDelta = offsetPos - offsetIndex; +// offset = offsets[offsetIndex] * (1 - offsetIndexDelta) + offsets[offsetIndex + 1] * offsetIndexDelta; +// projectedPolygon.push([x + x0, y + offset + y0]); +// } +// projectedPolygon = projectedPolygon.map(L.point); +// projectedPolygon = L.LineUtil.simplify(projectedPolygon, 1.5); +// if (!place.projectedPolygons) { +// place.projectedPolygons = []; +// } +// place.projectedPolygons[viewZoom] = projectedPolygon; +// } +// }, + +export default {getTileId, getWikimapiaTileCoords, parseTile, makeTileUrl} +\ No newline at end of file diff --git a/src/lib/tiled-data-loader/index.js b/src/lib/tiled-data-loader/index.js @@ -41,9 +41,9 @@ class TiledDataLoader { } calcAdjustment(layerTileCoords, dataTileCoords) { - if (layerTileCoords.x == dataTileCoords.x && - layerTileCoords.y == dataTileCoords.y && - layerTileCoords.z == dataTileCoords.z) { + if (layerTileCoords.x === dataTileCoords.x && + layerTileCoords.y === dataTileCoords.y && + layerTileCoords.z === dataTileCoords.z) { return null; } if (dataTileCoords.z > layerTileCoords.z) {