var nyc = nyc || {};
nyc.ol = nyc.ol || {};
nyc.ol.style = nyc.ol.style || {};
/**
* @public
* @namespace
*/
nyc.ol.style.mvt = nyc.ol.style.mvt || {};
/**
* @desc A function to create a proxy layer for styling points from an ol.layer.TileVector layer with format ol.format.MVT - WARNING: This function uses portions of the OpenLayers API that are only visible when using ol-debug.js
* @public
* @function
* @param {nyc.ol.style.mvt.ProxyPointLayerOptions} options Options for creating the style function
* @return {ol.layer.Vector}
*/
nyc.ol.style.mvt.proxyPointLayer = function(options){
var currentTile;
var map = options.map;
var mvtLayer = options.mvtLayer;
var grid = mvtLayer.getSource().getTileGrid();
var source = new ol.source.Vector({});
var mainStyle = mvtLayer.getStyle();
var proxyLayer = new ol.layer.Vector({
source: source,
style: options.pointStyle,
zIndex: mvtLayer.getZIndex() + 1,
visible: mvtLayer.getVisible()
});
map.addLayer(proxyLayer);
mvtLayer.on('change:visible', function(){
proxyLayer.setVisible(mvtLayer.getVisible());
});
var layerRenderer = map.getRenderer().getLayerRenderer(mvtLayer);
layerRenderer.drawTileImage = function(){
currentTile = arguments[0];
ol.renderer.canvas.VectorTileLayer.prototype.drawTileImage.apply(this, arguments);
};
mvtLayer.setStyle(
function(mvtFeature, resolution){
if (mvtFeature.getGeometry().getType() == 'Point'){
var fid = mvtFeature.get(options.fidProperty);
if (!source.getFeatureById(fid)){
var converted = nyc.ol.style.mvt.convertPointFeature(map, grid, currentTile, mvtFeature, fid);
source.addFeature(converted);
}
}else{
return mainStyle(mvtFeature, resolution);
}
}
);
return proxyLayer;
};
/**
* @desc Object type to hold arguments for {@link nyc.ol.style.mvt.withPointConversion}
* @public
* @typedef {Object}
* @property {ol.Map} map The map onto which the point feature will be rendered
* @property {ol.layer.VectorTile} mvtLayer The MVT vector tile layer
* @property {string} fidProperty The property name containing a unique id for features
* @property {ol.StyleFunction} pointStyle The style function for point features
*/
nyc.ol.style.mvt.ProxyPointLayerOptions;
/**
* @desc A function to convert ol.render.Feature to ol.Feature
* @private
* @function
* @param {ol.Map} map The map onto which the point feature will be rendered
* @param {ol.tilegrid.TileGrid} grid The tile grid containing the tile being rendered
* @param {ol.VectorTile} tile The tile containing the point feature
* @param {ol.render.Feature} feature The point feature
* @param {string|number} fid A unique id for the converted point feature
* @return {ol.Feature} feature The converted point feature
*/
nyc.ol.style.mvt.convertPointFeature = function(map, grid, tile, feature, fid){
var tileCoord = tile.getTileCoord();
var extent = grid.getTileCoordExtent(tileCoord);
var unitsPerPixel = grid.getResolution(tileCoord[0]);
var pixel = feature.getOrientedFlatCoordinates();
var x = extent[0] + (pixel[0] * unitsPerPixel);
var y = extent[3] - (pixel[1] * unitsPerPixel);
var point = new ol.geom.Point([x, y]);
var converted = new ol.Feature(feature.getProperties());
converted.setId(fid);
converted.setGeometry(point);
return converted;
};