odin_geolayer
odin_geolayer
is a generic application domain crate to display and post-process configured GeoJSON files that are
stored within the server file system (usually in ODIN_ROOT/data/odin_geolayer/
- see odin_build
for
details about the server filesytem structure). It is supposed to work with arbitrary GeoJSON that was generated by external tools but allows
to configure display specific attributes and Javascript functions that are used to control rendering on a per-file basis.
The odin_geolayer
crate itself only defines a GeoLayerService
and its odin_server::SpaService
implementation. The main function of this
micro service is to add a server route for mapping requests to its data directory in use, and to provide the two primary assets: the geolayer.js
JS module and its geolayer_config.js
companion (see Client Code).
JS module configuration
The geolayer_config.js
asset defines which GeoJSON sources can be displayed. It is presented to the user in form of a tree list in the
"Geo Layers" UI Window. While this is an ordinary Javascript source it has to define an exported config
object with
a source
property that holds a list of GeoJSON entries:
export const config = {
layer: {
name:"/overlay/annotation",
description:"static map overlays with symbolic data",
show: true,
},
sources: [
{ pathName: "utilities/powerlines/ca", // ① display path for UI window
file: './hifld/Electric_Power_Transmission_Lines-CA-100122.geojson', // ② relative file path of GeoJSON resource
info: 'HIFLD Electric Power Transmission Lines in CA 10/01/2022', // informal
date: '10/01/2022', // informal
render: { strokeWidth: 1.5, stroke: "#48D1CC", fill: "#48D1CC" } // ③ render options
},
{ pathName: 'utilities/substations/ca',
file: './hifld/Electric_Substations-CA-100122.geojson',
info: 'HIFLD electric substations in CA 10/01/2022',
date: '10/01/2022',
render: { markerSymbol: 's' }
},
{ pathName: 'emergency/fire_stations/ca',
file: './hifld/Fire_Stations-CA-100122.geojson.gz',
info: 'HIFLD fire stations in CA 10/01/2022',
date: '10/01/2022',
render: { markerSymbol: './asset/odin_geolayer/firestation.png', markerColor: 'red' } // ③ render options with marker symbol
},
...
{ pathName: 'boundaries/counties/CA',
file: './hifld/CA_County_Boundaries.geojson',
info: 'California county boundaries',
date: '10/01/2022',
render: { stroke: 'yellow', strokeWidth: 2, module: './county_boundaries.js' } // ④ render options with post-proc module
}
]
render: { // default render options
stroke: '#48D1CC',
stroke: '#48D1CC',
strokeWidth: 2,
fill: '#48D1CC',
markerColor: 'cyan',
markerSize: 32,
module: './extsym.js'
}
};
(1) The pathName
property of an entry specifies the tree list entry in the UI Window. It follows a normal filesystem scheme of
path elements separated by '/'. The heading path elements (e.g. utilities/powerlines
) can be used to categorize the entries. There
are no constraints of how to organize entries - categories can be chosen at will.
(2) The file
property contains a relative file path that is used to locate the resource on the server. It is not presented to the
user and hence does not have to be readable. Note this property can also include path elements preceeding the filename, to organize
such files within the server data directory. The file
property is relative to the server data directory (which is not known by
the client side).
(3) Each entry can have its own render options, including
stroke
- a color name (or CSS color specification string) for lines/outlinesstrokeWidth
for lines/outlinesfill
- fill color to use for polygonsmarkerSymbol
- specification of how to display markers. Either a single letter that is drawn within the marker symbol or an image filename to use instead of the default markermarkerColor
- symbol color to use
(4) Render options can include a module
property that specifies a Javascript file which should be used to post-process
the GeoJSON before it is rendered by Cesium. This is required if rendering should include GeoJSON feature properties such as
names, or rendering should use a different geometric type (e.g. a polyline instead of a polygon). Render modules have to
define an exported render()
function like so:
...
export function render (entityCollection, opts) {
for (const e of entityCollection.values) {
let props = e.properties;
if (e.polygon) {
// get feature properties that are display relevant
let name = getPropValue(props,'NAMELSAD');
let lat = getPropValue(props,'INTPTLAT');
let lon = getPropValue(props,'INTPTLON');
// add/modify Cesium.Entity display properties
if (name && lat && lon) {
e.position = Cesium.Cartesian3.fromDegrees(lon, lat);
e.label = {
text: name,
fillColor: opts.stroke,
...
};
}
}
...
}
}
function getPropValue(props,key) { // local helper functions
let p = props[key];
return p ? p._value : undefined; // note that p is a Cesium.Entity property (data has to be extracted from `_value`)
}
See the odin_geolayer/assets/
directory for more examples. Rendering modules are normal module assets following the
lookup rules defined in odin_build
.
Tools
The odin_geolayer
crate contains a show_geolayer
binary with a server that has a GeoLayerService
. This binary allows
to specify the geolayer data directory to use with a --data_dir <path>
command line option and hence is useful to test
geolayer_config.js
scripts. The default data directory is ODIN_ROOT/data/odin_geolayer/
.