commit ad7b4563d671e1bf0ad546702eb74886b3fb7f68
parent 1d1f9b32d92f436d0f731e842f507429c1544cb6
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Tue, 31 Jan 2017 02:15:26 +0300
[wikimapia] simplify polygons for faster processing
Diffstat:
3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/lib/leaflet.layer.wikimapia/index.js b/src/lib/leaflet.layer.wikimapia/index.js
@@ -33,7 +33,7 @@ L.Wikimapia = L.GridLayer.extend({
 
         onAdd: function(map) {
             if (!this.loader) {
-                this.loader = new WikimapiaLoader(map.project.bind(map));
+                this.loader = new WikimapiaLoader(map);
             }
             L.GridLayer.prototype.onAdd.call(this, map);
             this.on('tileunload', this.onTileUnload, this);
@@ -103,7 +103,6 @@ L.Wikimapia = L.GridLayer.extend({
             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;
diff --git a/src/lib/leaflet.layer.wikimapia/wikimapia-loader.js b/src/lib/leaflet.layer.wikimapia/wikimapia-loader.js
@@ -6,9 +6,9 @@ class WikimapiaLoader extends TiledDataLoader {
     maxZoom = 15;
     tileSize = 1024;
 
-    constructor(projectFunc) {
+    constructor(projectObj) {
         super();
-        this._project = projectFunc;
+        this._projectObj = projectObj;
 
     }
 
@@ -58,7 +58,7 @@ class WikimapiaLoader extends TiledDataLoader {
     }
 
     processResponse(xhr) {
-        return wmUtils.parseTile(xhr.response, this._project)
+        return wmUtils.parseTile(xhr.response, this._projectObj)
             .then((tileData) => {
                     return {
                         tileData,
diff --git a/src/lib/leaflet.layer.wikimapia/wm-utils.js b/src/lib/leaflet.layer.wikimapia/wm-utils.js
@@ -1,3 +1,5 @@
+import L from 'leaflet';
+
 // (1233,130,5) -> "032203"
 function getTileId({x, y, z}) {
     let id = [];
@@ -99,7 +101,7 @@ function decodePolygon(s) {
     return coords;
 }
 
-function makeCoordsLocal(line, tileCoords, projectFunc) {
+function makeCoordsLocal(line, tileCoords, projectObj) {
     const {x: tileX, y: tileY, z: tileZ} = tileCoords,
         x0 = tileX * 1024,
         y0 = tileY * 1024,
@@ -107,7 +109,7 @@ function makeCoordsLocal(line, tileCoords, projectFunc) {
     let latlon, p;
     for (let i = 0; i < line.length; i++) {
         latlon = line[i];
-        p = projectFunc(latlon, tileZ + 2);
+        p = projectObj.project(latlon, tileZ + 2);
         p.x -= x0;
         p.y -= y0;
         localCoords.push(p);
@@ -119,7 +121,28 @@ function asap() {
     return new Promise((resolve) => setTimeout(resolve, 0));
 }
 
-async function parseTile(s, projectFunc) {
+function simplifyPolygon(latlngs, tileCoords, projectObj) {
+    const
+        x = tileCoords.x * 1024,
+        y = tileCoords.y * 1024,
+        p0 = projectObj.unproject([x, y]),
+        p1 = projectObj.unproject([x + 1, y + 1]),
+        pixelDegSize = p0.lat - p1.lat;
+    let points = [];
+    for (let i = 0; i < latlngs.length; i++) {
+        let ll = latlngs[i];
+        points.push({x: ll[0], y: ll[1]});
+    }
+    points = L.LineUtil.simplify(points, pixelDegSize * 2);
+    latlngs = [];
+    for (let i = 0; i < points.length; i++) {
+        let p = points[i];
+        latlngs.push([p.x, p.y]);
+    }
+    return latlngs
+}
+
+async function parseTile(s, projectObj) {
     const tile = {};
     const places = tile.places = [];
     const lines = s.split('\n');
@@ -175,8 +198,8 @@ async function parseTile(s, projectFunc) {
             throw new Error(`Polygon has ${coords.length} points`);
         }
         place.polygon = coords;
-        place.localPolygon = makeCoordsLocal(coords, tile.coords, projectFunc);
-        // place.localBoundsWESN = makeBoundsLocal(place.boundsWESN);
+        let polygon = simplifyPolygon(coords, tile.coords, projectObj);
+        place.localPolygon = makeCoordsLocal(polygon, tile.coords, projectObj);
         places.push(place);
     }
     return tile;