@opengeoweb/webmap-react 9.1.0 → 9.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { Component, forwardRef, useContext, Children, isValidElement, cloneElement, useRef, useState, useEffect, useCallback, createRef, PureComponent } from 'react';
3
- import { legendImageStore, WMImageEventType, webmapUtils, getLegendGraphicURLForLayer, getMapImageStore, LayerType, WMBBOX, debugLogger, DebugType, WMLayer, WMJSMap, tilesettings } from '@opengeoweb/webmap';
3
+ import { legendImageStore, WMImageEventType, webmapUtils, getLegendGraphicURLForLayer, getMapImageStore, LayerType, WMBBOX, debugLogger, DebugType, WMLayer, WMJSMap, tilesettings, getWMJSMapById } from '@opengeoweb/webmap';
4
4
  import { CustomTooltip, ToolContainerDraggable, dateUtils, CustomIconButton } from '@opengeoweb/shared';
5
5
  import { jsx, jsxs } from 'react/jsx-runtime';
6
6
  import * as ReactDOM from 'react-dom';
@@ -55468,7 +55468,12 @@ class ReactMapView extends React.Component {
55468
55468
  onMapPinChangeLocation({
55469
55469
  mapPinLocation: {
55470
55470
  lat: mapPinLatLonCoordinate.lat,
55471
- lon: mapPinLatLonCoordinate.lon
55471
+ lon: mapPinLatLonCoordinate.lon,
55472
+ projectionX: mapPinLatLonCoordinate.projectionX,
55473
+ projectionY: mapPinLatLonCoordinate.projectionY,
55474
+ screenOffsetX: mapPinLatLonCoordinate.screenOffsetX,
55475
+ screenOffsetY: mapPinLatLonCoordinate.screenOffsetY,
55476
+ srs: mapPinLatLonCoordinate.srs
55472
55477
  },
55473
55478
  mapId
55474
55479
  });
@@ -56680,6 +56685,224 @@ const MapTime = ({
56680
56685
  }, mapTime)));
56681
56686
  };
56682
56687
 
56688
+ /* *
56689
+ * Licensed under the Apache License, Version 2.0 (the "License");
56690
+ * you may not use this file except in compliance with the License.
56691
+ * You may obtain a copy of the License at
56692
+ *
56693
+ * http://www.apache.org/licenses/LICENSE-2.0
56694
+ *
56695
+ * Unless required by applicable law or agreed to in writing, software
56696
+ * distributed under the License is distributed on an "AS IS" BASIS,
56697
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
56698
+ * See the License for the specific language governing permissions and
56699
+ * limitations under the License.
56700
+ *
56701
+ * Copyright 2023 - Koninklijk Nederlands Meteorologisch Instituut (KNMI)
56702
+ * Copyright 2023 - Finnish Meteorological Institute (FMI)
56703
+ * */
56704
+ const MS_IN_HOUR = 3600 * 1000;
56705
+ // The following is necessary to allow to assign to the CanvasRenderingContext2D ctx property
56706
+ /* eslint-disable no-param-reassign */
56707
+ /**
56708
+ * This component registers to a webmap instance and draws axis for height and time in the map using the Map Canvas.
56709
+ */
56710
+ const ProfileAxis = ({
56711
+ mapId
56712
+ }) => {
56713
+ const drawAxisOnMapDisplay = (ctx, webMap, axisStyle) => {
56714
+ const bbox = webMap.getBBOX();
56715
+ const width = webMap.getWidth();
56716
+ const height = webMap.getHeight();
56717
+ const offY = height - 50;
56718
+ const offX = 20;
56719
+ try {
56720
+ const startDate = new Date(bbox.left);
56721
+ const endDate = new Date(bbox.right);
56722
+ webMap.setMessage(`${startDate.toDateString()}, ${startDate.getUTCHours()} to ${endDate.getUTCHours()} hours UTC`);
56723
+ } catch (e) {
56724
+ webMap.setMessage('');
56725
+ }
56726
+ // Draw the horizontal time axis
56727
+ drawTimeAxis(ctx, bbox, offX, offY, width, height, axisStyle);
56728
+ // Draw the vertical elevation axis
56729
+ drawHeightAxis(ctx, bbox, offX, offY, width, height, axisStyle);
56730
+ // Draw the mouse cursor
56731
+ drawCursor(ctx, bbox, offX, offY, width, height, webMap, axisStyle);
56732
+ // Draw the layer name
56733
+ drawLayerName(ctx, bbox, offX, offY, width, height, webMap, axisStyle);
56734
+ };
56735
+ React__default.useEffect(() => {
56736
+ const axisStyle = {
56737
+ backgroundColor: 'white',
56738
+ color: 'black',
56739
+ fontStyleSmall: '10px Roboto, Helvetica, Arial',
56740
+ fontStyleBig: '14px Roboto, Helvetica, Arial'
56741
+ };
56742
+ // Draw on map canvas callback function
56743
+ const beforeCanvasDisplay = ctx => {
56744
+ drawAxisOnMapDisplay(ctx, getWMJSMapById(mapId), axisStyle);
56745
+ };
56746
+ // unMount logic
56747
+ const unMount = () => {
56748
+ const webMap = getWMJSMapById(mapId);
56749
+ if (webMap) {
56750
+ webMap.removeListener('beforecanvasdisplay', beforeCanvasDisplay);
56751
+ }
56752
+ };
56753
+ // Mount logic
56754
+ const webMap = getWMJSMapById(mapId);
56755
+ if (webMap && webMap.getProjection().srs === 'GFI:TIME_ELEVATION') {
56756
+ webMap.hideScaleBar();
56757
+ webMap.hideMouseCursorProperties();
56758
+ webMap.setTimeOffset('');
56759
+ webMap.addListener('beforecanvasdisplay', beforeCanvasDisplay, true);
56760
+ webMap.draw();
56761
+ }
56762
+ return unMount;
56763
+ }, [mapId]);
56764
+ return null;
56765
+ };
56766
+ /**
56767
+ * Calculates a time spacing. This is used to place labels on the X axis (time axis).
56768
+ * To make readable time labels, the time spacing is discretized to rounded times,
56769
+ * The time spacing changes according to zoom level.
56770
+ * @param bbox
56771
+ * @param width
56772
+ * @returns
56773
+ */
56774
+ const getTimeSpacingInMs = (bbox, width) => {
56775
+ const hoursInView = Math.abs(bbox.right - bbox.left) / (MS_IN_HOUR * width / 500);
56776
+ return Math.pow(2, Math.round((Math.log10(hoursInView / 10) + 0.5) / Math.log10(2)) - 1) * MS_IN_HOUR;
56777
+ };
56778
+ const drawTimeAxis = (ctx, bbox, offsetX, offsetY, width, height, axisStyle) => {
56779
+ const {
56780
+ backgroundColor,
56781
+ color,
56782
+ fontStyleSmall,
56783
+ fontStyleBig
56784
+ } = axisStyle;
56785
+ // Draw rectangle with backgroundColor for axis
56786
+ ctx.textBaseline = 'middle';
56787
+ ctx.fillStyle = backgroundColor;
56788
+ ctx.fillRect(0, offsetY, width, 50);
56789
+ ctx.font = fontStyleSmall;
56790
+ ctx.textAlign = 'left';
56791
+ ctx.fillStyle = color;
56792
+ ctx.strokeStyle = color;
56793
+ const ticksMs = getTimeSpacingInMs(bbox, width);
56794
+ const roundedTimeLeftMs = Math.round(bbox.left / ticksMs) * ticksMs;
56795
+ const roundedTimeRightMs = Math.round(bbox.right / ticksMs) * ticksMs;
56796
+ const numHoursInView = Math.min((roundedTimeRightMs - roundedTimeLeftMs) / ticksMs + 1, 100);
56797
+ for (let hoursToPlot = 0; hoursToPlot < numHoursInView; hoursToPlot += 1) {
56798
+ const timeMs = roundedTimeLeftMs + hoursToPlot * ticksMs;
56799
+ const posX = Math.round((timeMs - bbox.left) / (bbox.right - bbox.left) * width) + 0.5;
56800
+ ctx.beginPath();
56801
+ ctx.moveTo(posX, offsetY + 0);
56802
+ ctx.lineTo(posX, offsetY + 10);
56803
+ const date = new Date(timeMs);
56804
+ const hourString = `0${date.getUTCHours()}`.slice(-2);
56805
+ const minuteString = `:${`0${date.getUTCMinutes()}`.slice(-2)}`;
56806
+ const txt = `${hourString}${minuteString}`;
56807
+ ctx.stroke();
56808
+ ctx.fillText(`${txt}`, posX - 13, offsetY + 16);
56809
+ }
56810
+ // Draw units in map
56811
+ ctx.font = fontStyleBig;
56812
+ ctx.fillText('time UTC (h)', width / 2 - 10, offsetY + 38);
56813
+ };
56814
+ /**
56815
+ * Calculates a spacing for the height axis. This is used to place labels on the Y axis (height axis).
56816
+ * To make readable height labels, the height spacing is discretized to rounded elevations,
56817
+ * The spacing changes according to zoom level.
56818
+ * @param bbox
56819
+ * @param height
56820
+ * @returns
56821
+ */
56822
+ const getHeightSpacingInMs = (bbox, height) => {
56823
+ const numMeterInView = Math.abs(bbox.bottom - bbox.top) / height;
56824
+ return Math.pow(10, Math.round(Math.log10(numMeterInView * 100) + 0.5) - 1);
56825
+ };
56826
+ const drawHeightAxis = (ctx, bbox, offsetX, offsetY, width, height, axisStyle) => {
56827
+ const {
56828
+ backgroundColor,
56829
+ color,
56830
+ fontStyleSmall,
56831
+ fontStyleBig
56832
+ } = axisStyle;
56833
+ // Draw rectangle in backgroundColor for axis
56834
+ ctx.fillStyle = backgroundColor;
56835
+ ctx.fillRect(0, 0, 60 + offsetX, height);
56836
+ ctx.font = fontStyleSmall;
56837
+ ctx.textAlign = 'right';
56838
+ ctx.fillStyle = color;
56839
+ const ticksM = getHeightSpacingInMs(bbox, height);
56840
+ const roundedElevBottomMeter = Math.round(bbox.bottom / ticksM) * ticksM;
56841
+ const roundedElevTopMeter = Math.round(bbox.top / ticksM) * ticksM;
56842
+ const numKmInView = Math.min((roundedElevTopMeter - roundedElevBottomMeter) / ticksM + 1, 100);
56843
+ for (let kmToPlot = 0; kmToPlot < numKmInView; kmToPlot += 1) {
56844
+ const valueInKm = roundedElevBottomMeter + kmToPlot * ticksM;
56845
+ const posY = Math.round((bbox.top - valueInKm) / (bbox.top - bbox.bottom) * height) + 0.5;
56846
+ ctx.beginPath();
56847
+ ctx.moveTo(offsetX + 50, posY);
56848
+ ctx.lineTo(offsetX + 60, posY);
56849
+ ctx.stroke();
56850
+ const txt = valueInKm;
56851
+ ctx.fillText(`${txt}`, offsetX + 48, posY + 2);
56852
+ }
56853
+ // Draw height unit in axis
56854
+ ctx.font = axisStyle.fontStyleBig;
56855
+ ctx.save();
56856
+ ctx.translate(5, height / 2 - 50);
56857
+ ctx.rotate(-Math.PI / 2);
56858
+ ctx.font = fontStyleBig;
56859
+ ctx.fillText('height (m)', 5, 5);
56860
+ ctx.restore();
56861
+ ctx.fillStyle = backgroundColor;
56862
+ ctx.fillRect(0, height - 60, offsetX + 60, 60);
56863
+ // Draw line border for map
56864
+ ctx.moveTo(offsetX + 60, offsetY + 0.5);
56865
+ ctx.lineTo(width, offsetY + 0.5);
56866
+ ctx.moveTo(offsetX + 60.5, 0);
56867
+ ctx.lineTo(offsetX + 60.5, height - 50);
56868
+ ctx.stroke();
56869
+ };
56870
+ const drawCursor = (ctx, bbox, offsetX, offsetY, width, height, webMapJS, axisStyle) => {
56871
+ // Do not draw if mouse is not in the map
56872
+ if (webMapJS.mouseX < 5 && webMapJS.mouseY < 5) {
56873
+ return;
56874
+ }
56875
+ /* Draw cursor line */
56876
+ const mouseX = Math.round(webMapJS.mouseX) + 0.5;
56877
+ const mouseY = Math.round(webMapJS.mouseY) + 0.5;
56878
+ ctx.strokeStyle = '#303030';
56879
+ ctx.setLineDash([15, 5]);
56880
+ ctx.beginPath();
56881
+ ctx.moveTo(0, mouseY);
56882
+ ctx.lineTo(width, mouseY);
56883
+ ctx.moveTo(mouseX, 0);
56884
+ ctx.lineTo(mouseX, height);
56885
+ ctx.stroke();
56886
+ ctx.strokeStyle = axisStyle.color;
56887
+ ctx.lineWidth = 1;
56888
+ ctx.setLineDash([]);
56889
+ };
56890
+ const drawLayerName = (ctx, bbox, offsetX, offsetY, width, height, webMapJS, axisStyle) => {
56891
+ // Draw layername
56892
+ const layers = webMapJS.getLayers();
56893
+ if (layers.length > 0) {
56894
+ ctx.textBaseline = 'middle';
56895
+ ctx.fillStyle = axisStyle.backgroundColor;
56896
+ ctx.font = axisStyle.fontStyleBig;
56897
+ ctx.textAlign = 'left';
56898
+ ctx.fillStyle = axisStyle.color;
56899
+ ctx.strokeStyle = axisStyle.color;
56900
+ ctx.fillText(`Layer: ${layers[0].name}`, 10, offsetY + 38);
56901
+ }
56902
+ };
56903
+ // Re-enable the previousely disabled eslint rule
56904
+ /* eslint-enable no-param-reassign */
56905
+
56683
56906
  const MapView = _a => {
56684
56907
  var {
56685
56908
  children,
@@ -56733,7 +56956,9 @@ const MapView = _a => {
56733
56956
  top: 0,
56734
56957
  position: 'absolute'
56735
56958
  }
56736
- }, /*#__PURE__*/React.createElement(ZoomControls, {
56959
+ }, /*#__PURE__*/React.createElement(ProfileAxis, {
56960
+ mapId: mapId
56961
+ }), /*#__PURE__*/React.createElement(ZoomControls, {
56737
56962
  onZoomIn: () => {
56738
56963
  const wmjsMap = webmapUtils.getWMJSMapById(mapId);
56739
56964
  wmjsMap.zoomIn(undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeoweb/webmap-react",
3
- "version": "9.1.0",
3
+ "version": "9.2.0",
4
4
  "description": "GeoWeb react wrapper for webmap",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export interface ProfileAxisProps {
3
+ mapId: string;
4
+ }
5
+ /**
6
+ * This component registers to a webmap instance and draws axis for height and time in the map using the Map Canvas.
7
+ */
8
+ export declare const ProfileAxis: React.FC<ProfileAxisProps>;
@@ -0,0 +1 @@
1
+ import 'jest-canvas-mock';
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ export declare const ProfileAxisStory: {
3
+ (): React.ReactElement;
4
+ storyName: string;
5
+ };
6
+ declare const _default: {
7
+ title: string;
8
+ };
9
+ export default _default;
@@ -0,0 +1,17 @@
1
+ export type GFIResult = [{
2
+ data: {
3
+ '0': number;
4
+ };
5
+ }];
6
+ export declare const CEILONETSTATIONLAYERNAME = "hasceilometerWMONAME";
7
+ export declare const CEILONETPROFILELAYERPREFIX = "ceilonet_";
8
+ /**
9
+ * Connects a Map with a WMS layer with ceilometer stations to a Map withj profile layers.
10
+ * Clicking on the station map causes the layer in the profile map to be changed accordingly.
11
+ * The layername comes from a GetFeatureInfo request on the stations layer.
12
+ *
13
+ * @param mapIdWithProfileViewer
14
+ * @param mapIdWithCeilometerStations
15
+ * @returns
16
+ */
17
+ export declare const connectProfileMapViewToProfileStationsMapById: (mapIdWithProfileViewer: string, mapIdWithCeilometerStations: string) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import * as React from 'react';
2
+ export declare const MapViewProfile: {
3
+ (): React.ReactElement;
4
+ storyName: string;
5
+ };
6
+ declare const _default: {
7
+ title: string;
8
+ };
9
+ export default _default;
@@ -34,6 +34,11 @@ export interface ReactMapViewProps {
34
34
  export interface MapLocation {
35
35
  lat: number;
36
36
  lon: number;
37
+ screenOffsetX?: number;
38
+ screenOffsetY?: number;
39
+ projectionX?: number;
40
+ projectionY?: number;
41
+ srs?: string;
37
42
  }
38
43
  export interface MapPinLocationPayload {
39
44
  mapId: string;
@@ -0,0 +1,19 @@
1
+ import { LayerType } from '@opengeoweb/webmap';
2
+ /**
3
+ * Base URL of the adaguc-service where all profiles are configured
4
+ */
5
+ export declare const profileAdagucServiceBaseUrl = "https://geoservices.knmi.nl";
6
+ /** The station layer with overview of profile datasets */
7
+ export declare const profileStationLayer: {
8
+ service: string;
9
+ name: string;
10
+ style: string;
11
+ layerType: LayerType;
12
+ };
13
+ export declare const profileDataLayer: {
14
+ service: string;
15
+ name: string;
16
+ format: string;
17
+ enabled: boolean;
18
+ layerType: LayerType;
19
+ };