Source: ol/format/Waze.js

/**
 * @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