Skip to content

Commit

Permalink
Minor updates and fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
interkosmos committed Aug 23, 2024
1 parent d4509a4 commit 92439f4
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 97 deletions.
80 changes: 37 additions & 43 deletions app/dmweb.f90
Original file line number Diff line number Diff line change
Expand Up @@ -602,39 +602,41 @@ subroutine route_logs(env)
call dm_cgi_form(env, param)

! Read and validate parameters.
if (dm_is_error(dm_cgi_get(param, 'from', from)) .or. &
dm_is_error(dm_cgi_get(param, 'to', to)) .or. &
dm_is_error(dm_cgi_get(param, 'max_results', nresults))) then
call html_error('Missing or Invalid Parameters', error=E_INVALID)
exit response_block
end if
valid = .false.

valid = .true.
valid_block: block
! Mandatory parameters.
if (dm_is_error(dm_cgi_get(param, 'from', from))) exit valid_block
if (dm_is_error(dm_cgi_get(param, 'to', to))) exit valid_block
if (dm_is_error(dm_cgi_get(param, 'max_results', nresults))) exit valid_block

! Timestamps.
if (.not. dm_time_valid(from)) valid = .false.
if (.not. dm_time_valid(to)) valid = .false.
! Timestamps.
if (.not. dm_time_valid(from)) exit valid_block
if (.not. dm_time_valid(to)) exit valid_block

! Node id.
if (dm_is_ok(dm_cgi_get(param, 'node_id', node_id))) then
if (.not. dm_id_valid(node_id)) valid = .false.
end if
! Node id.
if (dm_is_ok(dm_cgi_get(param, 'node_id', node_id))) then
if (.not. dm_id_valid(node_id)) exit valid_block
end if

! Sensor id.
if (dm_is_ok(dm_cgi_get(param, 'sensor_id', sensor_id))) then
if (.not. dm_id_valid(sensor_id)) valid = .false.
end if
! Sensor id.
if (dm_is_ok(dm_cgi_get(param, 'sensor_id', sensor_id))) then
if (.not. dm_id_valid(sensor_id)) exit valid_block
end if

! Target id.
if (dm_is_ok(dm_cgi_get(param, 'target_id', target_id))) then
if (.not. dm_id_valid(target_id)) valid = .false.
end if
! Target id.
if (dm_is_ok(dm_cgi_get(param, 'target_id', target_id))) then
if (.not. dm_id_valid(target_id)) exit valid_block
end if

! Number of results.
if (.not. dm_array_has(max_results, nresults)) valid = .false.
! Number of results.
if (.not. dm_array_has(max_results, nresults)) exit valid_block

valid = .true.
end block valid_block

if (.not. valid) then
call html_error('Invalid Parameters', error=E_INVALID)
call html_error('Missing or Invalid Parameters', error=E_INVALID)
exit response_block
end if

Expand Down Expand Up @@ -724,6 +726,7 @@ subroutine route_map(env)

integer :: i, rc
integer :: nn, ns, nt
logical :: comma
real(kind=r8) :: lon, lat
type(db_type) :: db

Expand Down Expand Up @@ -789,38 +792,29 @@ subroutine route_map(env)
call dm_cgi_out('const lon = ' // dm_ftoa(lon) // ';')
call dm_cgi_out('const lat = ' // dm_ftoa(lat) // ';')
call dm_cgi_out('const zoom = 5;')
call dm_cgi_out('const features = [')
call dm_cgi_out('const geoJson = { "type": "FeatureCollection", "features": [')

nn = size(nodes)
ns = size(sensors)
nt = size(targets)

do i = 1, nn
if (i < nn .or. ns > 0 .or. nt > 0) then
call dm_cgi_out(dm_geojson_from(nodes(i)) // ',')
else
call dm_cgi_out(dm_geojson_from(nodes(i)))
end if
comma = (i < nn .or. ns > 0 .or. nt > 0)
call dm_cgi_out(dm_geojson_from(nodes(i), comma))
end do

do i = 1, ns
if (i < ns .or. nt > 0) then
call dm_cgi_out(dm_geojson_from(sensors(i)) // ',')
else
call dm_cgi_out(dm_geojson_from(sensors(i)))
end if
comma = (i < ns .or. nt > 0)
call dm_cgi_out(dm_geojson_from(sensors(i), comma))
end do

do i = 1, nt
if (i < nt) then
call dm_cgi_out(dm_geojson_from(targets(i)) // ',')
else
call dm_cgi_out(dm_geojson_from(targets(i)))
end if
comma = (i < nt)
call dm_cgi_out(dm_geojson_from(targets(i), comma))
end do

call dm_cgi_out('];')
call dm_cgi_out('createMap(id, url, lon, lat, zoom, features);')
call dm_cgi_out(']};')
call dm_cgi_out('createMap(id, url, lon, lat, zoom, geoJson);')
call dm_cgi_out(H_SCRIPT_END)

! Output page footer.
Expand Down
6 changes: 3 additions & 3 deletions man/dmlog.1
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
'\" t
.\" Title: dmlog
.\" Author: Philipp Engel
.\" Generator: Asciidoctor 2.0.16
.\" Date: 2024-08-09
.\" Generator: Asciidoctor 2.0.23
.\" Date: 2024-08-10
.\" Manual: User Commands
.\" Source: DMLOG
.\" Language: English
.\"
.TH "DMLOG" "1" "2024-08-09" "DMLOG" "User Commands"
.TH "DMLOG" "1" "2024-08-10" "DMLOG" "User Commands"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
Expand Down
58 changes: 34 additions & 24 deletions share/dmweb/dmpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,57 @@
* @param {number} lon - The longitude coordinate.
* @param {number} lat - The latitude coordinate.
* @param {number} zoom - The Leaflet zoom level.
* @param {array} features - Array of GeoJSON features.
* @param {array} geoJson - GeoJSON feature collection.
*/
function createMap(id, url, lon, lat, zoom, features)
function createMap(id, url, lon, lat, zoom, geoJson)
{
const options = { attributionControl: false };
const view = { lat: lat, lng: lon };
const maxZoom = 22;
const map = L.map(id, options).setView(view, zoom);
const maxZoom = { maxZoom: 24 };

L.tileLayer(url, { maxZoom: maxZoom }).addTo(map);
const map = L.map(id, options).setView(view, zoom);

const geoJson = { "type": "FeatureCollection", "features": features };
L.tileLayer(url, maxZoom).addTo(map);

L.geoJson(geoJson, {
pointToLayer,
onEachFeature
}).addTo(map);
}

/**
* Returns true if type is valid.
*/
function isValidType(type)
{
return (type == 'node' || type == 'sensor' || type == 'target');
}

/**
* Leaflet callback function.
*/
function onEachFeature(feature, layer)
{
const base = '/dmpack';

let content = '';

if (feature.properties && feature.properties.type && feature.properties.data)
{
if (feature.properties.data.name)
if (feature.properties.data.id && features.properties.data.name)
{
content += `<strong>${feature.properties.data.name}</strong> (${feature.properties.type})<br>`;
}
let name;

if (feature.properties.data.meta)
{
content += feature.properties.data.meta;
if (isValidType(features.properties.type))
name = `<a href="${base}/${features.properties.type}?id=${feature.properties.data.id}">${feature.properties.data.name}</a>`;
else
name = `${feature.properties.data.name}`;

content += `<strong>${name}</strong> `;
}

content += `<em>${feature.properties.type}</em><br>`;
if (feature.properties.data.meta) content += feature.properties.data.meta;
}

layer.bindPopup(content);
Expand All @@ -55,6 +69,12 @@ function onEachFeature(feature, layer)
*/
function pointToLayer(feature, latlng)
{
const colors = {
node: "gold",
sensor: "crimson",
target: "chartreuse"
};

let options = {
radius: 4,
fillColor: "black",
Expand All @@ -64,18 +84,8 @@ function pointToLayer(feature, latlng)
fillOpacity: 0.8
};

switch (feature.properties.type)
{
case 'node':
options.fillColor = "gold";
break;
case 'sensor':
options.fillColor = "crimson";
break;
case 'target':
options.fillColor = "chartreuse";
break;
}
if (feature.properties && feature.properties.type && colors.hasOwnProperty(feature.properties.type))
options.fillColor = colors[feature.properties.type];

return L.circleMarker(latlng, options);
}
66 changes: 39 additions & 27 deletions src/dm_geojson.f90
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ module dm_geojson
! ******************************************************************
! PUBLIC PROCEDURES.
! ******************************************************************
subroutine dm_geojson_feature_point(geojson, type, lon, lat, alt, data)
subroutine dm_geojson_feature_point(geojson, type, lon, lat, alt, data, comma)
!! Returns GeoJSON feature point of given DMPACK type, longitude,
!! latitude, altitude, and type data in JSON. The output string
!! `geojson` is of the following form:
Expand Down Expand Up @@ -74,104 +74,116 @@ subroutine dm_geojson_feature_point(geojson, type, lon, lat, alt, data)
!! ```
!!
!! The property _data_ is set to the passed JSON string `data`.
character(len=:), allocatable, intent(out) :: geojson !! Output GeoJSON string.
integer, intent(in) :: type !! Point type (`TYPE_NODE`, `TYPE_SENSOR`, `TYPE_TARGET`).
real(kind=r8), intent(in) :: lon !! Point longitude (decimal).
real(kind=r8), intent(in) :: lat !! Point latitude (decimal).
real(kind=r8), intent(in) :: alt !! Point altitude.
character(len=*), intent(in) :: data !! Point JSON data.
character(len=:), allocatable, intent(out) :: geojson !! Output GeoJSON string.
integer, intent(in) :: type !! Point type (`TYPE_NODE`, `TYPE_SENSOR`, `TYPE_TARGET`).
real(kind=r8), intent(in) :: lon !! Point longitude (decimal).
real(kind=r8), intent(in) :: lat !! Point latitude (decimal).
real(kind=r8), intent(in) :: alt !! Point altitude.
character(len=*), intent(in) :: data !! Point JSON data.
logical, intent(in), optional :: comma !! Append comma separator.

integer :: type_
logical :: comma_

type_ = TYPE_NONE
if (dm_type_valid(type)) type_ = type

comma_ = .false.
if (present(comma)) comma_ = comma

geojson = '{"type":"Feature","geometry":{"type":"Point","coordinates":[' // &
dm_ftoa(lon) // ',' // dm_ftoa(lat) // ',' // dm_ftoa(alt) // &
']},"properties":{"type":"' // trim(TYPE_NAMES(type_)) // '","data":' // &
trim(data) // '}}'
if (comma_) geojson = geojson // ','
end subroutine dm_geojson_feature_point

! ******************************************************************
! PRIVATE PROCEDURES.
! ******************************************************************
function geojson_from_node(node) result(geojson)
function geojson_from_node(node, comma) result(geojson)
!! Returns node as allocatable string in GeoJSON format.
use :: dm_node, only: node_type

type(node_type), intent(inout) :: node !! Node type.
character(len=:), allocatable :: geojson !! GeoJSON string.
type(node_type), intent(inout) :: node !! Node type.
logical, intent(in), optional :: comma !! Append comma separator.
character(len=:), allocatable :: geojson !! GeoJSON string.

call dm_geojson_feature_point(geojson, TYPE_NODE, node%lon, node%lat, node%alt, dm_json_from(node))
call dm_geojson_feature_point(geojson, TYPE_NODE, node%lon, node%lat, node%alt, dm_json_from(node), comma)
end function geojson_from_node

function geojson_from_sensor(sensor) result(geojson)
function geojson_from_sensor(sensor, comma) result(geojson)
!! Returns sensor as allocatable string in GeoJSON format.
use :: dm_sensor, only: sensor_type

type(sensor_type), intent(inout) :: sensor !! Sensor type.
character(len=:), allocatable :: geojson !! GeoJSON string.
type(sensor_type), intent(inout) :: sensor !! Sensor type.
logical, intent(in), optional :: comma !! Append comma separator.
character(len=:), allocatable :: geojson !! GeoJSON string.

call dm_geojson_feature_point(geojson, TYPE_SENSOR, sensor%lon, sensor%lat, sensor%alt, dm_json_from(sensor))
call dm_geojson_feature_point(geojson, TYPE_SENSOR, sensor%lon, sensor%lat, sensor%alt, dm_json_from(sensor), comma)
end function geojson_from_sensor

function geojson_from_target(target) result(geojson)
function geojson_from_target(target, comma) result(geojson)
!! Returns target as allocatable string in GeoJSON format.
use :: dm_target, only: target_type

type(target_type), intent(inout) :: target !! Target type.
character(len=:), allocatable :: geojson !! GeoJSON string.
type(target_type), intent(inout) :: target !! Target type.
logical, intent(in), optional :: comma !! Append comma separator.
character(len=:), allocatable :: geojson !! GeoJSON string.

call dm_geojson_feature_point(geojson, TYPE_TARGET, target%lon, target%lat, target%alt, dm_json_from(target))
call dm_geojson_feature_point(geojson, TYPE_TARGET, target%lon, target%lat, target%alt, dm_json_from(target), comma)
end function geojson_from_target

integer function geojson_write_node(node, unit) result(rc)
integer function geojson_write_node(node, unit, comma) result(rc)
!! Writes node to file or standard output.
use :: dm_node, only: node_type

type(node_type), intent(inout) :: node !! Node type.
integer, intent(in), optional :: unit !! File unit.
type(node_type), intent(inout) :: node !! Node type.
integer, intent(in), optional :: unit !! File unit.
logical, intent(in), optional :: comma !! Append comma separator.

integer :: stat, unit_

rc = E_WRITE
unit_ = stdout
if (present(unit)) unit_ = unit
write (unit_, '(a)', iostat=stat) dm_geojson_from(node)
write (unit_, '(a)', iostat=stat) dm_geojson_from(node, comma)
if (stat /= 0) return
rc = E_NONE
end function geojson_write_node

integer function geojson_write_sensor(sensor, unit) result(rc)
integer function geojson_write_sensor(sensor, unit, comma) result(rc)
!! Writes sensor to file or standard output.
use :: dm_sensor, only: sensor_type

type(sensor_type), intent(inout) :: sensor !! Sensor type.
integer, intent(in), optional :: unit !! File unit.
logical, intent(in), optional :: comma !! Append comma separator.

integer :: stat, unit_

rc = E_WRITE
unit_ = stdout
if (present(unit)) unit_ = unit
write (unit_, '(a)', iostat=stat) dm_geojson_from(sensor)
write (unit_, '(a)', iostat=stat) dm_geojson_from(sensor, comma)
if (stat /= 0) return
rc = E_NONE
end function geojson_write_sensor

integer function geojson_write_target(target, unit) result(rc)
integer function geojson_write_target(target, unit, comma) result(rc)
!! Writes target to file or standard output.
use :: dm_target, only: target_type

type(target_type), intent(inout) :: target !! Target type.
integer, intent(in), optional :: unit !! File unit.
logical, intent(in), optional :: comma !! Append comma separator.

integer :: stat, unit_

rc = E_WRITE
unit_ = stdout
if (present(unit)) unit_ = unit
write (unit_, '(a)', iostat=stat) dm_geojson_from(target)
write (unit_, '(a)', iostat=stat) dm_geojson_from(target, comma)
if (stat /= 0) return
rc = E_NONE
end function geojson_write_target
Expand Down
Loading

0 comments on commit 92439f4

Please sign in to comment.