function updateMapExtent(extent) {
   extent = extent || turf.extent($scope.map.geometry);
   map.fitBounds([
     [extent[1],extent[0]],
     [extent[3], extent[2]]
   ]);
 }
      it('should pull a tile containing the extent of the geometry for source ' + dataSource.id, function(done) {
        this.timeout(10000);
        startTest('Pull a tile containing the extent of the geometry for source ' + dataSource.id);
        if (!dataSource.geometry) {
          return done(new Error('no geom for source ' + dataSource.format));
        }
        var xyz = xyzTileUtils.getXYZFullyEncompassingExtent(turf.extent(dataSource.geometry));
        f.getTile('png', xyz.z, xyz.x, xyz.y, dataSource.testParams || {}, function(err, tileStream) {
          if (err) {
            console.log('there was an err', err);
            done(err);
            return;
          }

          should.exist(tileStream);

          var ws = fs.createOutputStream(path.join('/tmp', 'test_extent_'+dataSource.id+'.png'));
          ws.on('close', function() {
            endTest('Pull a tile containing the extent of the geometry for source ' + dataSource.id);

            done();
          });

          tileStream.pipe(ws);
        });
      });
Example #3
0
GeoPackage.prototype._calculateExtentFromGeometry = function(geometry) {
  var extent = turf.extent(geometry);
  extent[0] = Math.max(-180, extent[0]);
  extent[1] = Math.max(-85, extent[1]);
  extent[2] = Math.min(180, extent[2]);
  extent[3] = Math.min(85, extent[3]);
  return extent;
};
Example #4
0
module.exports = function (tileLayers, tile, writeData, done) {

  var footways = filterAndClipFootways(tileLayers.osm.osm, tile),
    roads = filterAndClipRoads(tileLayers.osm.osm, tile),
    proposals = [];
    
  var roadIndex = rbush();

  for(var r = 0; r < roads.length; r++) {
    roadIndex.insert(turf.extent(roads[r]).concat({road_id: r}));
  }

  for (var f = 0; f < footways.length; f++) {
    var segments = sliceAtIntersect(footways[f], findProbablyIntersects(footways[f], roadIndex, roads));

    // Find which of the remaining segments stay close to a road (should be a sidewalk)
    segments.features.forEach(function (segment) {
      // found a case where the original linestring is a single coordinate, not wrapped in an array
      if (segment.geometry.coordinates.length < 2 || !segment.geometry.coordinates[0].length) return;
      // skip short little segments
      if (turf.lineDistance(segment, 'miles') <= 10/5280) return;

      var segmented = lineChunk(segment, 250/5280, 'miles');
      
      segmented.features.forEach(function (seg) {
        if (turf.lineDistance(seg, 'miles') <= 150/5280) return;
        
        // Get bisectors fo this segment, and match it against 
        // each road. 
        var bisectors = buildBisectors(seg);
        var isMatched = false;

        var bisectBox = turf.extent(turf.featurecollection(bisectors));
        var maybeCollides = roadIndex.search(bisectBox);

        maybeCollides.forEach(function (maybe) {
          var road = roads[maybe[4].road_id];
        
          if (isMatched || road.properties.layer !== footways[f].properties.layer) return;

          var matched = 0;
          bisectors.forEach(function (bisector) {
            if (gju.lineStringsIntersect(bisector.geometry, road.geometry)) matched++;
          });
          if (matched / bisectors.length > 0.7) {
            isMatched = true;
            seg.properties['_osm_way_id'] = footways[f].properties._osm_way_id;
            seg.properties['proposed:footway'] = 'sidewalk';
            seg.properties['proposed:associatedStreet'] = road.properties.name;
            writeData(JSON.stringify(seg)+'\n');
          }
        });
      });
    });
  }

  done(null, proposals);
};
MapcacheCreateController.prototype._calculateCacheSize = function() {
  if (!this.tileCacheRequested || !this.cache.source || isNaN(this.cache.minZoom) || isNaN(this.cache.maxZoom) || !this.cache.geometry) {
    this.totalCacheSize = 0;
    this.totalCacheTiles = 0;
    return;
  }

  var extent = turf.extent(this.cache.geometry);
  this.totalCacheTiles = xyzTileUtils.tileCountInExtent(extent, this.cache.minZoom, this.cache.maxZoom);
  this.totalCacheSize = this.totalCacheTiles * (this.cache.source.tileSize/this.cache.source.tileSizeCount);
};
Example #6
0
 _.forIn(clusters, function (cluster) {
     var pointsCollection = turf.featurecollection(cluster.venuePoints);
     var center = turf.center(pointsCollection);
     var bbox = turf.extent(pointsCollection);
     var radius = fastDistance(turf.point(bbox.slice(0,2)), center);
     _.assign(center.properties, cluster, {
         radius: radius,
         bbox: bbox
     });
     features.push(center);
 });
Example #7
0
/**
 * Using our rbush index, find which roads probably intersect the sidewalk
 */
function findProbablyIntersects(footway, roadIndex, roads) {
  var extent = turf.extent(footway);

  var colliding = roadIndex.search(extent);
  var fc = [];


  for (var i = 0; i < colliding.length; i++) {
    fc.push(roads[colliding[i][4].road_id])
  }

  return turf.featurecollection(fc);
}
 $scope.$watch('map.mapcacheUrl', function() {
   if (!$scope.map) return;
   if ($scope.map.dataSources) {
     var merged = _.reduce($scope.map.dataSources, function(merge, dataSource) {
       if (dataSource.geometry) {
         return turf.union(merge, dataSource.geometry);
       }
       return merge;
     }, $scope.map.dataSources[0].geometry);
     updateMapExtent(turf.extent(merged));
   }
   addMapLayer();
 });
  function showCache(cache) {
    if (!highlightedCache) {
      oldCenter = map.getCenter();
      oldZoom = map.getZoom();
    }
    highlightedCache = cache;

    var extent = turf.extent(cache.geometry);
    map.fitBounds([
      [extent[1],extent[0]],
      [extent[3], extent[2]]
    ], {animate: false});
    showCacheTiles(cache);
  }
Example #10
0
Map.prototype.getOverviewTile = function(callback) {
  var merged;
  for (var i = 0; i < this.map.dataSources.length; i++) {
    var ds = this.map.dataSources[i];
    if (ds.geometry && !merged) {
      merged = ds.geometry;
    } else {
      merged = turf.union(merged, ds.geometry);
    }
  }

  var extent;
  if (merged) {
    extent = turf.extent(merged);
  } else {
    extent = [-180, -85, 180, 85];
  }
  var xyz = xyzTileUtils.getXYZFullyEncompassingExtent(extent);
  this.getTile('png', xyz.z, xyz.x, xyz.y, {}, callback);
};
  return function(input, operation, option) {
    if (!input) return null;

  	if (operation === 'extent') {
      var e = turf.extent(input);
      if (option) {
        switch(option) {
          case 'w':
          return e[0];
          case 's':
          return e[1];
          case 'e':
          return e[2];
          case 'n':
          return e[3];
        }
      }
  		return null;
  	}
    return input;
  };
Example #12
0
  return redis.lrange('polygoncity:job:' + id + ':footprints', 0, -1).then(function(results) {
    results.forEach(function(footprint) {
      footprints.push(JSON.parse(footprint));
    });

    for (var i = 0; i < footprints.length; i++) {
      features.push(footprints[i]);
    }

    var featureCollection = turf.featurecollection(features);

    // Add bounding box according to GeoJSON spec
    // http://geojson.org/geojson-spec.html#bounding-boxes
    var bbox = turf.extent(featureCollection);
    featureCollection.bbox = bbox;

    var _outputPath = path.join(outputPath, 'index.geojson');

    console.log('Number of GeoJSON footprints:', footprints.length);

    return fs.outputFileAsync(_outputPath, JSON.stringify(featureCollection));
  });
  $scope.$watch('caches', function(caches) {
    if (!caches) return;
    cacheCenters = [];

    for (var i = 0; i < caches.length; i++) {
      var cache = caches[i];
      if (!cacheFootprints[cache.id]) {
        createRectangle(cache);
      }
    }

    if (!centered) {
      if (cacheCenters && cacheCenters.length > 0) {
        var extent = turf.extent(turf.featurecollection(cacheCenters));
        map.fitBounds([
          [extent[1],extent[0]],
          [extent[3], extent[2]]
        ], {animate: false});
      }
      centered = true;
    }
  });
Example #14
0
module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var bbox = turf.extent(layer);
  var bboxLineString = turf.bboxPolygon(bbox);
  bboxLineString.geometry.type = 'LineString';
  bboxLineString.geometry.coordinates = bboxLineString.geometry.coordinates[0];
  var buffer = turf.buffer(bboxLineString, 0.0005, 'miles').features[0];

  var result = layer.features.filter(function(val) {
    val.properties._osmlint = 'unclosedways';
    var valueType = (
      preserveType.area[val.properties.area] ||
      preserveType.building[val.properties.building] ||
      preserveType.landuse[val.properties.landuse] ||
      preserveType.aeroway[val.properties.aeroway] ||
      preserveType.leisure[val.properties.leisure] ||
      preserveType.natural[val.properties.natural] ||
      preserveType.man_made[val.properties.man_made]
    );

    if (val.geometry.type === 'LineString' && valueType) {
      var coordinates = val.geometry.coordinates;
      var firstCoord = coordinates[0];
      var lastCoord = coordinates[coordinates.length - 1];
      if (turf.inside(turf.point(firstCoord), buffer) || turf.inside(turf.point(lastCoord), buffer)) {
        return false;
      }
      return true;
    }
  });

  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }

  done(null, null);
};
Example #15
0
/*
 * Takes a feature collection and creates a bounding box that contains all of
 * the features, auto-calculates an appropriate cell width based on the width
 * of the box, then turns creates a hexgrid.
 */
function create_hexgrids(json) {

	// Create the bounding box using features from both the download and upload
	// throughput data.
	var updown = turf.featurecollection(json.download.features.concat(json.upload.features));
	// The combined up/down features will be used to add a map layer with a
	// scatter plot of all the data points.
	fs.writeFileSync(dirs.geojson + sub_dir + '-plot.json', JSON.stringify(updown));
	var bbox = turf.extent(updown);
	var bbox_poly = turf.bboxPolygon(bbox);
	var point1 = turf.point(bbox_poly.geometry.coordinates[0][0]);
	var point2 = turf.point(bbox_poly.geometry.coordinates[0][1]);
	var distance = turf.distance(point1, point2, 'miles');

	var hexgrids =  {
		low : turf.hex(bbox, cell_widths.low, 'miles'),
		medium : turf.hex(bbox, cell_widths.medium, 'miles'),
		high : turf.hex(bbox, cell_widths.high, 'miles'),
	}

	return hexgrids;

}
Example #16
0
	function determineGeometry(callback) {
		if (rawgeojson) {
			geojson = JSON.parse(rawgeojson);
		} else if (argv.f) {
			geojson = JSON.parse(fs.readFileSync(argv.file, 'utf8'));
		} else if (argv.p) {
			var coords = String(argv.point).split(',').map(parseFloat);
			geojson = turf.point([coords[1], coords[0]]);
		} else if (argv.e) {
			var coords = String(argv.extent).split(',').map(parseFloat);
			var input = turf.featurecollection([
				turf.point([coords[1], coords[0]]),
				turf.point([coords[3], coords[2]])
			]);
			geojson = turf.bboxPolygon(turf.extent(input));
		} else {
			displayHelp();
			console.error('No geometry provided. Pipe geojson, or use --point or --extent');
			return process.exit(1);
		}

		if (argv.b) {
			var radius = parseFloat(argv.buffer);
			var units = /mi$/.test(argv.buffer) ? 'miles' : 'kilometers';
			geojson = turf.buffer(geojson, radius, units);
		}
		
		// tilecover doesn't like features
		if(geojson.tupe === "FeatureCollection") {       
			geojson = turf.merge(geojson);
		}
		if (geojson.type === 'Feature') {
			geojson = geojson.geometry;
		}

		callback();
	},
Example #17
0
module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var highways = {};
  var bboxes = [];
  var majorRoads = {
    'motorway': true,
    'trunk': true,
    'primary': true,
    'secondary': true,
    'tertiary': true,
    'motorway_link': true,
    'trunk_link': true,
    'primary_link': true,
    'secondary_link': true,
    'tertiary_link': true
  };
  var minorRoads = {
    'unclassified': true,
    'residential': true,
    'living_street': true,
    'service': true,
    'road': true
  };
  var pathRoads = {
    'pedestrian': true,
    'track': true,
    'footway': true,
    'path': true,
    'cycleway': true,
    'steps': true
  };
  var preserveType = {};
  preserveType = _.extend(preserveType, majorRoads);
  preserveType = _.extend(preserveType, minorRoads);
  //preserveType = _.extend(preserveType, pathRoads);
  var osmlint = 'overlaphighways';

  for (var i = 0; i < layer.features.length; i++) {
    var val = layer.features[i];
    if (preserveType[val.properties.highway] && (val.geometry.type === 'LineString' || val.geometry.type === 'MultiLineString') && val.properties.layer === undefined) {
      var bboxHighway = turf.extent(val);
      bboxHighway.push(val.properties._osm_way_id);
      bboxes.push(bboxHighway);
      highways[val.properties._osm_way_id] = val;
    }
  }
  var traceTree = rbush(bboxes.length);
  traceTree.load(bboxes);
  var output = {};
  for (var j = 0; j < bboxes.length; j++) {
    var bbox = bboxes[j];
    var overlaps = traceTree.search(bbox);
    for (var k = 0; k < overlaps.length; k++) {
      var overlap = overlaps[k];
      if (bbox[4] !== overlap[4]) {
        var fromHighway = highways[bbox[4]];
        var toHighway = highways[overlap[4]];
        var intersect = turf.intersect(toHighway, fromHighway);
        if (intersect !== undefined && (intersect.geometry.type === 'LineString' || intersect.geometry.type === 'MultiLineString')) {
          var coordinates = intersect.geometry.coordinates;
          var type;
          if (majorRoads[fromHighway.properties.highway] && majorRoads[toHighway.properties.highway]) {
            type = 'major-major';
          } else if ((majorRoads[fromHighway.properties.highway] && minorRoads[toHighway.properties.highway]) || (minorRoads[fromHighway.properties.highway] && majorRoads[toHighway.properties.highway])) {
            type = 'major-minor';
          } else if ((majorRoads[fromHighway.properties.highway] && pathRoads[toHighway.properties.highway]) || (pathRoads[fromHighway.properties.highway] && majorRoads[toHighway.properties.highway])) {
            type = 'major-path';
          } else if (minorRoads[fromHighway.properties.highway] && minorRoads[toHighway.properties.highway]) {
            type = 'minor-minor';
          } else if ((minorRoads[fromHighway.properties.highway] && pathRoads[toHighway.properties.highway]) || (pathRoads[fromHighway.properties.highway] && minorRoads[toHighway.properties.highway])) {
            type = 'minor-path';
          } else if (pathRoads[fromHighway.properties.highway] && pathRoads[toHighway.properties.highway]) {
            type = 'path-path';
          }

          var props = {
            _osmlint: osmlint,
            _fromWay: bbox[4],
            _toWay: overlap[4],
            _type: type
          };
          if (intersect.geometry.type === 'MultiLineString') {
            for (var l = 0; l < coordinates.length; l++) {
              var coor = coordinates[l];
              output[coor[0]] = turf.point(coor[0], props);
              output[coor[coor.length - 1]] = turf.point(coor[coor.length - 1], props);
            }
          } else {
            output[coordinates[0]] = turf.point(coordinates[0], props);
            output[coordinates[coordinates.length - 1]] = turf.point(coordinates[coordinates.length - 1], props);
          }
          fromHighway.properties._osmlint = osmlint;
          toHighway.properties._osmlint = osmlint;
          output[bbox[4]] = fromHighway;
          output[overlap[4]] = toHighway;
        }
      }
    }
  }
  var result = _.values(output);

  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }

  done(null, null);

};
Example #18
0
  this.autorun(function(computation) {
    const data = Template.currentData();

    if (computation.firstRun) {
      return;
    }

    // Update map size (required when header becomes visible)
    Tracker.afterFlush(function() {
      map.resize();
    });

    // Update tracker layer
    if (data.tracker && data.tracker.lat && data.tracker.lon) {
      point.coordinates = [
        data.tracker.lon,
        data.tracker.lat
      ];

      pointSource.setData(point);

      showTracker(true);

      // Ease or jump to target
      const isOld = tracker && tracker._id == data.tracker._id;

      const easeOptions = {
        center: point.coordinates,
        duration: isOld ? 750 : 0
      };

      if (! isOld) {
        easeOptions.zoom = 14;
      }

      map.easeTo(easeOptions);
    } else {
      showTracker(false);
    }

    // Update history layer
    if (data.history) {
      history.coordinates = data.history.points;
      historySource.setData(history);

      if (! data.tracker) {
        const extent = turf.extent({
          type: 'Feature',
          geometry: history
        });

        map.fitBounds(margin.map(function(offset, index) {
          return extent[index] + offset;
        }), {
          linear: true,
          duration: 0
        });
      }

      showHistory(true);
    } else {
      showHistory(false);
      history.coordinates = [];
    }

    tracker = data.tracker;
  });
exports.createXYZTiles = function(xyzSource, minZoom, maxZoom, downloadTile, shouldContinueFunction, zoomLevelCompleteFunction, callback) {
    xyzSource.status.zoomLevelStatus = xyzSource.status.zoomLevelStatus || [];

    var extent = turf.extent(xyzSource.geometry);
    extent[0] = Math.max(-180, extent[0]);
    extent[1] = Math.max(-85, extent[1]);
    extent[2] = Math.min(180, extent[2]);
    extent[3] = Math.min(85, extent[3]);
    console.log('extent', extent);

    var totalXYZTiles = 0;

    for (var zoom = minZoom; zoom <= maxZoom; zoom++) {
      var yRange = xyzTileUtils.yCalculator(extent, zoom);
      var xRange = xyzTileUtils.xCalculator(extent, zoom);
      console.log('zoom level %d yRange', zoom, yRange);
      console.log('zoom level %d xRange', zoom, xRange);

      var totalTiles = (1 + (yRange.max - yRange.min)) * (1 + (xRange.max - xRange.min));
      totalXYZTiles += totalTiles;
      xyzSource.status.zoomLevelStatus[zoom] = xyzSource.status.zoomLevelStatus[zoom] || {
        complete: false,
        totalTiles: totalTiles,
        generatedTiles: 0
      };
      if (xyzSource.status.zoomLevelStatus[zoom].complete) {
        xyzSource.status.zoomLevelStatus[zoom].generatedTiles = totalTiles;
      }
    }
    xyzSource.markModified('status.zoomLevelStatus');
    xyzSource.status.totalTiles = totalXYZTiles;
    xyzSource.save(function() {
      var zoom = minZoom;

      async.whilst(
        function (stop) {
          return zoom <= maxZoom && !stop;
        },
        function (zoomLevelDone) {
          console.log("Starting zoom level " + zoom);

          shouldContinueFunction(xyzSource, function(err, keepGoing) {
            if (!keepGoing) {
              zoom++;
              return zoomLevelDone();
            }
            console.log("Continuing to create zoom level " + zoom);
            var yRange = xyzTileUtils.yCalculator(extent, zoom);
            var xRange = xyzTileUtils.xCalculator(extent, zoom);

            var currentx = xRange.min;

            async.doWhilst(
              function(xRowDone) {
                getXRow(xyzSource, currentx, yRange, zoom, xRowDone, downloadTile, shouldContinueFunction);
              },
              function (stop) {
                console.log("x row " + currentx + " is done");
                currentx++;
                return currentx <= xRange.max && !stop;
              },
              function () {
                console.log("Zoom level " + zoom + " is complete.");
                zoomLevelCompleteFunction(xyzSource, zoom, function() {
                  zoom++;
                  zoomLevelDone();
                });
              }
            );
          });
        },
        function (err) {
          console.log("done with all the zoom levels");
          callback(err, xyzSource);
        }
      );
    });
}
Example #20
0
module.exports = function(geo, opts){
  if(!opts) opts = {};
  // normalize geojson data
  var fc = JSON.parse(JSON.stringify(geo));
  fc = flatten(normalize(fc));

  // parse options
  // fixed pixel zoom
  var zoom;
  if(opts.z) zoom = parseFloat(opts.z);
  if(opts.zoom) zoom = parseFloat(opts.zoom);
  // frame buffer
  var frame = 1;
  if(opts.f) frame = opts.f;
  if(opts.frame) frame = opts.frame;
  // overzoom mod
  var mod = 0;
  if(opts.m) mod = opts.m;
  if(opts.mod) mod = opts.mod;
  // fixed tile and bbox frame
  if(opts.b && typeof opts.b === 'string') opts.bbox = opts.b.split('=').join('').split(',').map(parseFloat);
  else if(opts.b) opts.bbox = opts.b;

  if(opts.bbox && typeof opts.bbox === 'string') opts.bbox = opts.bbox.split('=').join('').split(',').map(parseFloat);
  else if(opts.bbox) opts.bbox = opts.bbox;
  else if(opts.t) opts.bbox = tilebelt.tileToBBOX(opts.t.split('/').map(parseFloat));
  else if(opts.tile) opts.bbox = tilebelt.tileToBBOX(opts.tile.split('/').map(parseFloat));

  // clip geometries to bbox
  if(opts.bbox) {
    var bboxPoly = turf.bboxPolygon(opts.bbox);
    fc.features = fc.features.map(function(f){
      var intersect = turf.intersect(bboxPoly, f);
      if(intersect) return intersect;
    });
    fc.features = fc.features.filter(function(f){
      if(f) return f;
    });
  }

  // auto pixel zoom if not specified
  if(!(zoom>0)) {
    var bbox = turf.extent(fc);
    var found = false;
    var z = 3;
    while(!found && z < 28) {
      // x fit
      var lineTilesX = tileCover.tiles(
          turf.linestring([[bbox[0], bbox[1]], [bbox[2], bbox[1]]]).geometry,
          {min_zoom: z, max_zoom: z}
        );
      var lineXs = lineTilesX.map(function(t){ return t[0]; });
      var lineMinX = lineXs.reduce(function(a, b){
        if(a < b) return a;
        else return b;
      });
      var lineMaxX = lineXs.reduce(function(a, b){
        if(a > b) return a;
        else return b;
      });
      var diffX = lineMaxX - lineMinX;

      // y fit
      var lineTilesY = tileCover.tiles(
          turf.linestring([[bbox[0], bbox[1]], [bbox[0], bbox[3]]]).geometry,
          {min_zoom: z, max_zoom: z}
        );
      var lineYs = lineTilesY.map(function(t){return t[1]; });
      var lineMinY = lineYs.reduce(function(a, b){
        if(a < b) return a;
        else return b;
      });
      var lineMaxY = lineYs.reduce(function(a, b){
        if(a > b) return a;
        else return b;
      });
      var diffY = lineMaxY - lineMinY;

      if (diffX > 30 || diffY > 23) {
        found = true;
        zoom = z;
      }
      z++;
    }
  }

  // apply overzoom mod
  zoom += mod;

  // rasterize geometries to tile pixels
  var tiles = [];
  fc.features.forEach(function(f) {
    var newTiles = tileCover.tiles(f.geometry, {min_zoom: zoom, max_zoom: zoom})
      .map(function(t){
        t[2] = f.geometry.type;
        return t;
      });
    tiles = tiles.concat(newTiles);
  });

  // fit frame to bbox and filter out of scope tile pixels
  if(opts.bbox) {
    // override frame if bbox or tile is given
    frame = 0;
    var topLeft = tilebelt.pointToTile(opts.bbox[0], opts.bbox[3], zoom);
    var bottomRight = tilebelt.pointToTile(opts.bbox[2], opts.bbox[1], zoom);
    // clip tile pixels outside the bbox frame
    tiles = tiles.filter(function(t) {
      if(t[0] >= topLeft[0] &&
         t[0] <= bottomRight[0] &&
         t[1] >= topLeft[1] &&
         t[1] <= bottomRight[1]) return true;
    });
    tiles.push(topLeft);
    tiles.push(bottomRight);
  }

  // find frame tile pixel bounds
  var xs = tiles.map(function(t){return t[0]; });
  var ys = tiles.map(function(t) { return t[1]; });
  var minX = xs.reduce(function(a, b){
    if(a < b) return a;
    else return b;
  });
  var minY = ys.reduce(function(a, b){
    if(a < b) return a;
    else return b;
  });
  var maxX = xs.reduce(function(a, b){
    if(a > b) return a;
    else return b;
  });
  var maxY = ys.reduce(function(a, b){
    if(a > b) return a;
    else return b;
  });

  // apply frame buffer
  minX -= frame;
  minY -= frame;
  maxX += frame;
  maxY += frame;

  var tileHash = {};
  tiles.forEach(function(tile){
    tileHash[tile[0]+'/'+tile[1]] = tile[2];
  });

  // write tile pixels
  var map = '';
  var x = minX;
  var y = minY;
  while(y <= maxY) {
    while(x <= maxX) {
      if(tileHash[x+'/'+y]) {
        if(tileHash[x+'/'+y] === 'Polygon' || tileHash[x+'/'+y] === 'MultiPolygon') map+=colors.bgGreen.green('::');
        else if(tileHash[x+'/'+y] === 'LineString' || tileHash[x+'/'+y] === 'MultiLineString') map+=colors.bgBlack.black('XX');
        else if(tileHash[x+'/'+y] === 'Point' || tileHash[x+'/'+y] === 'MultiPoint') map+=colors.bgRed.red('@@');
        else map+=colors.bgBlue('  ');
      }
      else map+=colors.bgBlue('  ');
      x++;
    }
    map+='\n';
    x = minX;
    y++;
  }

  // output ascii render
  return map;
}
Example #21
0
module.exports = function(tileLayers, tile, writeData, done) {
  var layer = tileLayers.osm.osm;
  var highways = {};
  var waterways = {};
  var highwaybboxes = [];
  var waterwaybboxes = [];
  var preserveType = {
    'motorway': true,
    'motorway_link': true,
    'primary': true,
    'primary_link': true,
    'secondary': true,
    'secondary_link': true,
    'tertiary': true,
    'tertiary_link': true,
    'trunk': true,
    'trunk_link': true,
    'residential': true,
    'unclassified': true,
    'living_street': true,
    'road': true
    //'service': true
  };
  var dontPreserveWaterways = {
    'dam': true,
    'weir': true,
    'waterfall': true
  };
  var fords = {};
  var osmlint = 'crossingwaterwayshighways';

  for (var i = 0; i < layer.features.length; i++) {
    var val = layer.features[i];
    var bbox;
    if (preserveType[val.properties.highway] && val.geometry.type === 'LineString' && val.properties.bridge === undefined && val.properties.tunnel === undefined && val.properties.ford === undefined) {
      bbox = turf.extent(val);
      bbox.push(val.properties._osm_way_id);
      highwaybboxes.push(bbox);
      highways[val.properties._osm_way_id] = val;
    } else if (val.properties.waterway && (val.geometry.type === 'LineString' || val.geometry.type === 'Polygon') && !dontPreserveWaterways[val.properties.waterway]) {
      if (val.geometry.type === 'Polygon') {
        val.geometry.type = 'LineString';
        val.geometry.coordinates = val.geometry.coordinates[0];
      }
      bbox = turf.extent(val);
      bbox.push(val.properties._osm_way_id);
      waterwaybboxes.push(bbox);
      waterways[val.properties._osm_way_id] = val;
    } else if (val.properties.ford === 'yes' && val.geometry.type === 'Point') {
      fords[val.geometry.coordinates.join(',')] = true;
    }
  }

  var traceTree = rbush(highwaybboxes.length);
  traceTree.load(highwaybboxes);
  var output = {};

  for (var j = 0; j < waterwaybboxes.length; j++) {
    var waterbbox = waterwaybboxes[j];
    var overlaps = traceTree.search(waterbbox);
    for (var k = 0; k < overlaps.length; k++) {
      var overlap = overlaps[k];
      var intersect = turf.intersect(highways[overlap[4]], waterways[waterbbox[4]]);
      if (intersect !== undefined) {
        var props = {
          idHighway: overlap[4],
          idWaterway: waterbbox[4],
          _osmlint: osmlint
        };
        intersect.properties = props;
        highways[overlap[4]].properties._osmlint = osmlint;
        waterways[waterbbox[4]].properties._osmlint = osmlint;
        output[overlap[4]] = highways[overlap[4]];
        output[waterbbox[4]] = waterways[waterbbox[4]];
        if (intersect.geometry.type === 'MultiPoint') {
          var coord = intersect.geometry.coordinates;
          for (var l = 0; l < coord.length; l++) {
            if (!fords[coord[l].join(',')]) {
              var point = turf.point(coord[l]);
              point.properties = props;
              output[waterbbox[4].toString().concat(l)] = point;
            }
          }
        } else if (intersect.geometry.type === 'Point' && !fords[intersect.geometry.coordinates.join(',')]) {
          output[waterbbox[4].toString().concat('P')] = intersect;
        }
      }
    }
  }

  var result = _.values(output);

  if (result.length > 0) {
    var fc = turf.featurecollection(result);
    writeData(JSON.stringify(fc) + '\n');
  }

  done(null, null);
};
Example #22
0
areas['areas'].forEach(function(area) {
  var geoJsonPath = 'geojson/' + area['code'] + '.geojson';
  try {
    fs.accessSync(geoJsonPath, fs.F_OK);

    var geoJson = JSON.parse(fs.readFileSync(geoJsonPath, 'utf8'));
    var feature = geoJson['features'][0];
    var points = area['tileCount'];

    var bbox = turf.extent(feature);
    var poly = turf.bboxPolygon(bbox);
    var polyArea = turf.area(feature);
    var bboxArea = turf.area(poly);
    var ratio = bboxArea / polyArea;
    var adjustedPoints = Math.ceil(points * ratio);

    var mpp = Math.ceil(Math.sqrt(bboxArea / adjustedPoints));

    var bbox = turf.extent(feature);
    var fc = turf.featurecollection([feature]);
    var gridPoints = turf.pointGrid(bbox, mpp * 0.001, 'kilometers');

    var matrix = [];
    var row = -1;
    var rowCoordinate = 0;

    gridPoints['features'].forEach(function(point) {
      var coordinates = point['geometry']['coordinates'];

      if (coordinates[0] != rowCoordinate) {
        row++;
        rowCoordinate = coordinates[0];
        matrix.push([]);
      }

      matrix[row].push(coordinates);
    });

    var sparseMatrix = []

    for(var i = 0; i < matrix.length; i++) {
      sparseMatrix[i] = [];
      for(var j = 0; j < matrix[0].length; j++) {
        sparseMatrix[i][j] = undefined;
      }
    }

    var filteredPoints = turf.within(gridPoints, fc);

    matrix.forEach(function(row, index) {
      row.forEach(function(coordinates, rowIndex) {
        var found = 0;
        filteredPoints['features'].forEach(function(point) {
          if (point['geometry']['coordinates'] === coordinates) {
            found = 1;
          }
        });
        sparseMatrix[index][rowIndex] = found;
      });
    });
  } catch (e) {
    var sparseMatrix = [[1, 1][1, 1]];
  }

  // console.log(sparseMatrix);
  newJson[area['code']] = Object.assign({ matrix: sparseMatrix }, area);

  // var newGeoJson = turf.combine(filteredPoints);
});
Example #23
0
  progressCallback(cache, function(err, updatedCache) {
    cache = updatedCache;
    xyzTileUtils.iterateAllTilesInExtent(turf.extent(cache.geometry), cache.minZoom, cache.maxZoom, cache, function(tile, tileDone) {
        var dir = path.join(self.config.outputDirectory, cacheId.toString(), 'xyztiles', tile.z.toString(), tile.x.toString());
        var filename = tile.y + '.png';

        if (fs.existsSync(path.join(dir, filename)) && (!cache.cacheCreationParams || (cache.cacheCreationParams && !cache.cacheCreationParams.noCache))) {
          log.info('[Tile Exists]:\t %d %d %d for the xyz cache %s', tile.z, tile.x, tile.y, cacheId.toString());
          cache.formats.xyz.zoomLevelStatus[tile.z].generatedTiles++;
          cache.formats.xyz.zoomLevelStatus[tile.z].percentComplete = 100 * cache.formats.xyz.zoomLevelStatus[tile.z].generatedTiles / cache.formats.xyz.zoomLevelStatus[tile.z].totalTiles;
          cache.formats.xyz.generatedTiles++;
          cache.formats.xyz.percentComplete = 100 * cache.formats.xyz.generatedTiles/cache.formats.xyz.totalTiles;

          fs.stat(path.join(dir, filename), function(err, stat) {
            cache.formats.xyz.size += stat.size;
            cache.formats.xyz.zoomLevelStatus[tile.z].size += stat.size;
            progressCallback(cache, function(err, updatedCache) {
              cache = updatedCache;
              return tileDone(null, tile);
            });
        	});
        } else {
          self.cache.getTile('png', tile.z, tile.x, tile.y, cache.cacheCreationParams, function(err, stream) {
            console.log('Get Tile returned error and stream', err, !!stream);
            if (err) {
              log.error(err);
              return tileDone(null, null);
            } else if (!stream) {
              log.error('There was no tile for ' + path.join(dir, filename));
              return tileDone(null, null);
            }
            var ws = fs.createOutputStream(path.join(dir, filename));
            stream.pipe(ws);
            ws.on('finish', function(){
              log.info('[Saved Tile]:\t\t %d %d %d for the xyz cache %s', tile.z, tile.x, tile.y, cacheId.toString());
              cache.formats.xyz.zoomLevelStatus[tile.z].generatedTiles++;
              cache.formats.xyz.zoomLevelStatus[tile.z].percentComplete = 100 *  cache.formats.xyz.zoomLevelStatus[tile.z].generatedTiles / cache.formats.xyz.zoomLevelStatus[tile.z].totalTiles;
              cache.formats.xyz.generatedTiles++;
              cache.formats.xyz.percentComplete = 100 * cache.formats.xyz.generatedTiles/cache.formats.xyz.totalTiles;

              fs.stat(path.join(dir, filename), function(err, stat) {
                cache.formats.xyz.size += stat.size;
                cache.formats.xyz.zoomLevelStatus[tile.z].size += stat.size;
                progressCallback(cache, function(err, updatedCache) {
                  cache = updatedCache;
                  return tileDone(null, tile);
                });
            	});
            });
          });
        }
      },
      function(zoom, callback) {
        log.info('[Zoom Level Done]:\t %d for %s', zoom, cacheId.toString());
        cache.formats.xyz.zoomLevelStatus[zoom].complete = true;
        progressCallback(cache, function(err, updatedCache) {
          cache = updatedCache;
          callback();
        });
      },
      function(err, data) {
        log.info('%s: %s', 'Cache is complete'.bold.bgBlue.yellow, cacheId.toString());
        data.formats.xyz.complete = true;
        self.cache.cache = data;
        callback(null, self.cache);
      }
    );
  });