@globalfishingwatch/layer-composer
Advanced tools
Comparing version 0.3.1 to 0.3.2
@@ -27,17 +27,54 @@ "use strict"; | ||
this.type = exports.VESSEL_EVENTS_TYPE; | ||
this._getStyleSources = function (layer) { | ||
var id = layer.id, data = layer.data; | ||
this._setActiveEvent = function (data, currentEvent) { | ||
var featureCollection = __assign({}, data); | ||
featureCollection.features = featureCollection.features.map(function (feature) { | ||
var newFeature = __assign({}, feature); | ||
var geom = feature.geometry; | ||
var featureLng = geom.coordinates[0]; | ||
var featureLat = geom.coordinates[1]; | ||
newFeature.properties = newFeature.properties || {}; | ||
newFeature.properties.active = | ||
currentEvent !== null && | ||
featureLng === currentEvent.position.lng && | ||
featureLat === currentEvent.position.lat; | ||
return newFeature; | ||
}); | ||
featureCollection.features.sort(function (a, b) { | ||
if (a.properties && a.properties.active) | ||
return 1; | ||
else if (b.properties && b.properties.active) | ||
return -1; | ||
else | ||
return 0; | ||
}); | ||
return featureCollection; | ||
}; | ||
this._getStyleSources = function (config) { | ||
var id = config.id, data = config.data; | ||
if (!data) { | ||
console.warn(exports.VESSEL_EVENTS_TYPE + " source generator needs geojson data", layer); | ||
// console.warn(`${VESSEL_EVENTS_TYPE} source generator needs geojson data`, config) | ||
return []; | ||
} | ||
var newData = __assign({}, data); | ||
if (config.currentEvent) { | ||
newData = _this._setActiveEvent(newData, config.currentEvent); | ||
} | ||
if (config.start && config.end) { | ||
var startMs_1 = new Date(config.start).getTime(); | ||
var endMs_1 = new Date(config.end).getTime(); | ||
newData.features = newData.features.filter(function (feature) { | ||
return (feature.properties && | ||
feature.properties.timestamp > startMs_1 && | ||
feature.properties.timestamp < endMs_1); | ||
}); | ||
} | ||
var source = { | ||
type: 'geojson', | ||
data: data || null, | ||
data: newData, | ||
}; | ||
return [__assign({ id: id }, source)]; | ||
}; | ||
this._getStyleLayers = function (layer) { | ||
if (!layer.data) { | ||
console.warn(exports.VESSEL_EVENTS_TYPE + " source generator needs geojson data", layer); | ||
this._getStyleLayers = function (config) { | ||
if (!config.data) { | ||
// console.warn(`${VESSEL_EVENTS_TYPE} source generator needs geojson data`, config) | ||
return []; | ||
@@ -50,3 +87,3 @@ } | ||
type: 'circle', | ||
source: layer.id, | ||
source: config.id, | ||
paint: { | ||
@@ -61,3 +98,3 @@ 'circle-color': ['get', 'color'], | ||
id: 'vessel_events', | ||
source: layer.id, | ||
source: config.id, | ||
type: 'symbol', | ||
@@ -73,7 +110,7 @@ layout: { | ||
}; | ||
this.getStyle = function (layer) { | ||
this.getStyle = function (config) { | ||
return { | ||
id: layer.id, | ||
sources: _this._getStyleSources(layer), | ||
layers: _this._getStyleLayers(layer), | ||
id: config.id, | ||
sources: _this._getStyleSources(config), | ||
layers: _this._getStyleLayers(config), | ||
}; | ||
@@ -105,15 +142,24 @@ }; | ||
exports.getVesselEventsGeojson = function (trackEvents) { | ||
var featureCollection = { | ||
type: 'FeatureCollection', | ||
features: [], | ||
}; | ||
if (!trackEvents) | ||
return null; | ||
return { | ||
type: 'FeatureCollection', | ||
features: trackEvents.map(function (event) { return ({ | ||
return featureCollection; | ||
featureCollection.features = trackEvents.map(function (event) { | ||
var authorized = event.encounter && event.encounter.authorized === true; | ||
var authorizationStatus = event.encounter | ||
? event.encounter.authorizationStatus | ||
: 'unmatched'; | ||
var lng = event.position.lng || event.position.lon || 0; | ||
return { | ||
type: 'Feature', | ||
properties: { | ||
type: event.type, | ||
active: event.active, | ||
timestamp: event.timestamp, | ||
timestamp: event.start, | ||
authorized: authorized, | ||
authorizationStatus: authorizationStatus, | ||
icon: "carrier_portal_" + event.type, | ||
color: event.type === 'encounter' | ||
? getEncounterAuthColor(event.authorizationStatus) | ||
? getEncounterAuthColor(authorizationStatus) | ||
: EVENTS_COLORS[event.type], | ||
@@ -123,7 +169,8 @@ }, | ||
type: 'Point', | ||
coordinates: [event.coordinates.lng, event.coordinates.lat], | ||
coordinates: [lng, event.position.lat], | ||
}, | ||
}); }), | ||
}; | ||
}; | ||
}); | ||
return featureCollection; | ||
}; | ||
//# sourceMappingURL=vessel-events.js.map |
@@ -116,3 +116,2 @@ "use strict"; | ||
this.latestGenerated = {}; | ||
this.globalGeneratorConfig = {}; | ||
} | ||
@@ -119,0 +118,0 @@ // Latest step in the workflow which compose the output needed for mapbox-gl |
@@ -5,8 +5,16 @@ /// <reference types="mapbox-gl" /> | ||
export declare const VESSEL_EVENTS_TYPE = "VESSEL_EVENTS"; | ||
interface CurrentEvent { | ||
position: { | ||
lat: number; | ||
lng: number; | ||
}; | ||
} | ||
export interface VesselEventsGeneratorConfig extends GeneratorConfig { | ||
data: FeatureCollection; | ||
currentEvent?: CurrentEvent; | ||
} | ||
declare class VesselsEventsGenerator { | ||
type: string; | ||
_getStyleSources: (layer: VesselEventsGeneratorConfig) => { | ||
_setActiveEvent: (data: FeatureCollection<import("geojson").Geometry, import("geojson").GeoJsonProperties>, currentEvent: CurrentEvent) => FeatureCollection<import("geojson").Geometry, import("geojson").GeoJsonProperties>; | ||
_getStyleSources: (config: VesselEventsGeneratorConfig) => { | ||
type: "geojson"; | ||
@@ -28,4 +36,4 @@ data?: string | FeatureCollection<import("geojson").Geometry, import("geojson").GeoJsonProperties> | import("geojson").Feature<import("geojson").Geometry, import("geojson").GeoJsonProperties> | undefined; | ||
}[]; | ||
_getStyleLayers: (layer: VesselEventsGeneratorConfig) => any[]; | ||
getStyle: (layer: VesselEventsGeneratorConfig) => { | ||
_getStyleLayers: (config: VesselEventsGeneratorConfig) => any[]; | ||
getStyle: (config: VesselEventsGeneratorConfig) => { | ||
id: string; | ||
@@ -54,28 +62,16 @@ sources: { | ||
declare type AuthorizationOptions = 'authorized' | 'partially' | 'unmatched'; | ||
declare type Event = { | ||
declare type RawEvent = { | ||
id: string; | ||
type: string; | ||
active: boolean; | ||
timestamp: number; | ||
authorizationStatus: AuthorizationOptions; | ||
coordinates: { | ||
lng: number; | ||
position: { | ||
lng?: number; | ||
lon?: number; | ||
lat: number; | ||
}; | ||
start: number; | ||
encounter?: { | ||
authorized: boolean; | ||
authorizationStatus: AuthorizationOptions; | ||
}; | ||
}; | ||
export declare const getVesselEventsGeojson: (trackEvents: Event[] | null) => { | ||
type: string; | ||
features: { | ||
type: string; | ||
properties: { | ||
type: string; | ||
active: boolean; | ||
timestamp: number; | ||
icon: string; | ||
color: string; | ||
}; | ||
geometry: { | ||
type: string; | ||
coordinates: number[]; | ||
}; | ||
}[]; | ||
} | null; | ||
export declare const getVesselEventsGeojson: (trackEvents: RawEvent[] | null) => FeatureCollection<import("geojson").Geometry, import("geojson").GeoJsonProperties>; |
@@ -16,3 +16,2 @@ /// <reference types="mapbox-gl" /> | ||
latestGenerated: any; | ||
globalGeneratorConfig: GlobalGeneratorConfig; | ||
constructor(params?: LayerComposerOptions); | ||
@@ -19,0 +18,0 @@ _getGeneratorSources: (layers: GeneratorStyles[]) => { |
{ | ||
"name": "@globalfishingwatch/layer-composer", | ||
"version": "0.3.1", | ||
"version": "0.3.2", | ||
"description": "Tools to convert layer configuration to data structures needed in Mapbox GL GFW interactive maps ", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
import { GeneratorConfig } from 'layer-composer/types' | ||
import { FeatureCollection } from 'geojson' | ||
import { FeatureCollection, Point } from 'geojson' | ||
import { GeoJSONSourceRaw } from 'mapbox-gl' | ||
@@ -8,4 +8,12 @@ import { Dictionary } from 'types' | ||
interface CurrentEvent { | ||
position: { | ||
lat: number | ||
lng: number | ||
} | ||
} | ||
export interface VesselEventsGeneratorConfig extends GeneratorConfig { | ||
data: FeatureCollection | ||
currentEvent?: CurrentEvent | ||
} | ||
@@ -18,13 +26,52 @@ | ||
_getStyleSources = (layer: VesselEventsGeneratorConfig) => { | ||
const { id, data } = layer | ||
_setActiveEvent = (data: FeatureCollection, currentEvent: CurrentEvent): FeatureCollection => { | ||
const featureCollection = { ...data } | ||
featureCollection.features = featureCollection.features.map((feature) => { | ||
const newFeature = { ...feature } | ||
const geom = feature.geometry as Point | ||
const featureLng = geom.coordinates[0] | ||
const featureLat = geom.coordinates[1] | ||
newFeature.properties = newFeature.properties || {} | ||
newFeature.properties.active = | ||
currentEvent !== null && | ||
featureLng === currentEvent.position.lng && | ||
featureLat === currentEvent.position.lat | ||
return newFeature | ||
}) | ||
featureCollection.features.sort((a, b) => { | ||
if (a.properties && a.properties.active) return 1 | ||
else if (b.properties && b.properties.active) return -1 | ||
else return 0 | ||
}) | ||
return featureCollection | ||
} | ||
_getStyleSources = (config: VesselEventsGeneratorConfig) => { | ||
const { id, data } = config | ||
if (!data) { | ||
console.warn(`${VESSEL_EVENTS_TYPE} source generator needs geojson data`, layer) | ||
// console.warn(`${VESSEL_EVENTS_TYPE} source generator needs geojson data`, config) | ||
return [] | ||
} | ||
let newData: FeatureCollection = { ...data } | ||
if (config.currentEvent) { | ||
newData = this._setActiveEvent(newData, config.currentEvent) | ||
} | ||
if (config.start && config.end) { | ||
const startMs = new Date(config.start).getTime() | ||
const endMs = new Date(config.end).getTime() | ||
newData.features = newData.features.filter((feature) => { | ||
return ( | ||
feature.properties && | ||
feature.properties.timestamp > startMs && | ||
feature.properties.timestamp < endMs | ||
) | ||
}) | ||
} | ||
const source: GeoJSONSourceRaw = { | ||
type: 'geojson', | ||
data: data || null, | ||
data: newData, | ||
} | ||
@@ -34,5 +81,5 @@ return [{ id, ...source }] | ||
_getStyleLayers = (layer: VesselEventsGeneratorConfig) => { | ||
if (!layer.data) { | ||
console.warn(`${VESSEL_EVENTS_TYPE} source generator needs geojson data`, layer) | ||
_getStyleLayers = (config: VesselEventsGeneratorConfig) => { | ||
if (!config.data) { | ||
// console.warn(`${VESSEL_EVENTS_TYPE} source generator needs geojson data`, config) | ||
return [] | ||
@@ -46,3 +93,3 @@ } | ||
type: 'circle', | ||
source: layer.id, | ||
source: config.id, | ||
paint: { | ||
@@ -57,3 +104,3 @@ 'circle-color': ['get', 'color'], | ||
id: 'vessel_events', | ||
source: layer.id, | ||
source: config.id, | ||
type: 'symbol', | ||
@@ -70,7 +117,7 @@ layout: { | ||
getStyle = (layer: VesselEventsGeneratorConfig) => { | ||
getStyle = (config: VesselEventsGeneratorConfig) => { | ||
return { | ||
id: layer.id, | ||
sources: this._getStyleSources(layer), | ||
layers: this._getStyleLayers(layer), | ||
id: config.id, | ||
sources: this._getStyleSources(config), | ||
layers: this._getStyleLayers(config), | ||
} | ||
@@ -83,11 +130,16 @@ } | ||
type AuthorizationOptions = 'authorized' | 'partially' | 'unmatched' | ||
type Event = { | ||
type RawEvent = { | ||
id: string | ||
type: string | ||
active: boolean | ||
timestamp: number | ||
authorizationStatus: AuthorizationOptions | ||
coordinates: { | ||
lng: number | ||
position: { | ||
lng?: number | ||
lon?: number | ||
lat: number | ||
} | ||
start: number | ||
encounter?: { | ||
authorized: boolean | ||
authorizationStatus: AuthorizationOptions | ||
} | ||
} | ||
@@ -116,17 +168,28 @@ | ||
export const getVesselEventsGeojson = (trackEvents: Event[] | null) => { | ||
if (!trackEvents) return null | ||
export const getVesselEventsGeojson = (trackEvents: RawEvent[] | null): FeatureCollection => { | ||
const featureCollection: FeatureCollection = { | ||
type: 'FeatureCollection', | ||
features: [], | ||
} | ||
return { | ||
type: 'FeatureCollection', | ||
features: trackEvents.map((event: Event) => ({ | ||
if (!trackEvents) return featureCollection | ||
featureCollection.features = trackEvents.map((event: RawEvent) => { | ||
const authorized = event.encounter && event.encounter.authorized === true | ||
const authorizationStatus = event.encounter | ||
? event.encounter.authorizationStatus | ||
: ('unmatched' as AuthorizationOptions) | ||
const lng = event.position.lng || event.position.lon || 0 | ||
return { | ||
type: 'Feature', | ||
properties: { | ||
type: event.type, | ||
active: event.active, | ||
timestamp: event.timestamp, | ||
timestamp: event.start, | ||
authorized, | ||
authorizationStatus, | ||
icon: `carrier_portal_${event.type}`, | ||
color: | ||
event.type === 'encounter' | ||
? getEncounterAuthColor(event.authorizationStatus) | ||
? getEncounterAuthColor(authorizationStatus) | ||
: EVENTS_COLORS[event.type], | ||
@@ -136,6 +199,8 @@ }, | ||
type: 'Point', | ||
coordinates: [event.coordinates.lng, event.coordinates.lat], | ||
coordinates: [lng, event.position.lat], | ||
}, | ||
})), | ||
} | ||
} | ||
}) | ||
return featureCollection | ||
} |
@@ -24,3 +24,2 @@ import Generators from './generators' | ||
latestGenerated: any | ||
globalGeneratorConfig: GlobalGeneratorConfig | ||
@@ -35,4 +34,2 @@ constructor(params?: LayerComposerOptions) { | ||
this.latestGenerated = {} | ||
this.globalGeneratorConfig = {} | ||
} | ||
@@ -39,0 +36,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1875483
14100