/** * @module nyc/ol/format/Waze */ import OlFeature from 'ol/Feature' import Point from 'ol/geom/Point' import LineString from 'ol/geom/LineString' import OlFormatFeature from 'ol/format/Feature' import OlFormatFormatType from 'ol/format/FormatType' import Style from 'ol/style/Style' import Stroke from 'ol/style/Stroke' import Fill from 'ol/style/Fill' import Circle from 'ol/style/Circle' /** * @desc Class to create features from Carto SQL API data. This format requires the presence of a WTK geometry in the source data with the column name wkt_geom. * @public * @class * @extends ol.format.Feature * @see http://openlayers.org/en/latest/apidoc/module-ol_format_Feature-FeatureFormat.html */ class Waze extends OlFormatFeature { /** * @desc Create an instance of CartoSql * @public * @constructor * @param {module:nyc/ol/format/Waze~Waze.Options} options Constructor options */ constructor(options) { super() /** * @private * @member {ol.ProjectionLike} */ this.dataProjection = 'EPSG:4326' /** * @private * @member {ol.ProjectionLike} */ this.featureProjection = options ? options.featureProjection : 'EPSG:3857' } /** * @desc Read a single feature from a source * @public * @method * @param {Object} source A Waze alert or jam object * @return {ol.Feature} Feature */ readFeature(source) { const feature = new OlFeature(source) try { const location = source.location let geom if (location) { geom = new Point([location.x, location.y]) } else { const coords = [] source.line.forEach(coord => { coords.push([coord.x, coord.y]) }) geom = new LineString(coords) } geom.transform(this.dataProjection, this.featureProjection) feature.setGeometry(geom) } catch (badGeom) { console.error(badGeom) feature.setGeometry(new Point([0, 0])) } feature.setId(source.uuid) feature.setStyle(Waze.Style) return feature } /** * @desc Read all features from a source * @public * @method * @param {string} source Response from a Carto SQL data source * @return {Array.<ol.Feature>} Features */ readFeatures(source) { const features = [] const waze = JSON.parse(source) waze.jams.forEach(jam => { features.push(this.readFeature(jam)) }) waze.alerts.forEach(alert => { features.push(this.readFeature(alert)) }) return features } /** * @desc Read the projection from a source * @public * @override * @method * @param {Document|Node|Object|string} source Source * @return {ol.proj.Projection} The projection */ readProjection(source) { return this.dataProjection } /** * @desc Get the extent from the source of the last readFeatures call * @public * @override * @method * @return {ol.Extent} The extent */ getLastExtent() { return null } /** * @desc Return format type * @public * @override * @method * @return {ol.format.FormatType} The format type */ getType() { return OlFormatFormatType.TEXT } } /** * @desc Constructor options for {@link module:nyc/ol/format/Waze~Waze} * @public * @typedef {Object} * @property {string} [featureProjection=EPSG:3857] The feature projection needed for the map */ Waze.Options Waze.TypeColors = { ACCIDENT: 'yellow', JAM: 'orange', ROAD_CLOSED: 'red', WEATHERHAZARD: 'blue', Small: 'yellow', Medium: 'orange', Large: 'red' } Waze.Style = (feature, resolution) => { if (feature.getGeometry().getType() === 'Point') { return new Style({ image: new Circle({ radius: 5, stroke: new Stroke({color: '#000'}), fill: new Fill({ color: Waze.TypeColors[feature.get('type')] || '#000' }) }) }) } else { return new Style({ stroke: new Stroke({ width: 5, color: Waze.TypeColors[feature.get('type')] || '#000' }) }) } } export default Waze