@vidro/map-handler 1.3.15 → 2.0.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/README.md +67 -1
- package/map-handler.d.ts +134 -0
- package/package.json +10 -4
- package/src/types.d.ts +63 -0
- package/.babelrc +0 -6
- package/doc/animation.png +0 -0
- package/doc/confirmComponent.png +0 -0
- package/doc/giswater.png +0 -0
- package/doc/giswaterInfo.png +0 -0
- package/doc/giswaterInfoApi.png +0 -0
- package/doc/giswatergeojson.png +0 -0
- package/doc/multiTile.png +0 -0
- package/doc/multiTileNoGutter.png +0 -0
- package/doc/togglelayergiswater.png +0 -0
- package/doc/vidromaps-basic.png +0 -0
- package/examples/full/apidemo.js +0 -387
- package/examples/full/cachedToken.dat +0 -1
- package/examples/full/cachedTokenData.dat +0 -1
- package/examples/full/docker/Docker_compose.yml +0 -14
- package/examples/full/docker/Dockerfile +0 -27
- package/examples/full/index.php +0 -200
- package/examples/full/storeToken.php +0 -6
- package/examples/full/tester.css +0 -74
- package/examples/full/tester.js +0 -658
- package/examples/multipleIframes/index.js +0 -82
- package/examples/multipleIframes/index.php +0 -52
- package/examples/react-next/README.md +0 -282
- package/examples/react-next/atoms/PrintLayoutSelector.js +0 -51
- package/examples/react-next/atoms/PrintPaperSizeSelector.js +0 -49
- package/examples/react-next/atoms/PrintScaleSelector.js +0 -61
- package/examples/react-next/atoms/ZoomToScaleButton.js +0 -57
- package/examples/react-next/components/AuthComponent.js +0 -88
- package/examples/react-next/components/MapButtons.js +0 -108
- package/examples/react-next/components/MapFilters.js +0 -120
- package/examples/react-next/components/MapIframe.js +0 -25
- package/examples/react-next/components/MapInfo.js +0 -36
- package/examples/react-next/components/MapLayers.js +0 -60
- package/examples/react-next/components/MapList.js +0 -51
- package/examples/react-next/components/MapPrint.js +0 -50
- package/examples/react-next/contexts/auth.js +0 -147
- package/examples/react-next/contexts/maps.js +0 -185
- package/examples/react-next/contexts/messages.js +0 -358
- package/examples/react-next/contexts/print.js +0 -125
- package/examples/react-next/env.sample +0 -3
- package/examples/react-next/eslint.config.mjs +0 -14
- package/examples/react-next/hooks/useMapEvents.js +0 -118
- package/examples/react-next/jsconfig.json +0 -7
- package/examples/react-next/next.config.mjs +0 -6
- package/examples/react-next/package.json +0 -25
- package/examples/react-next/pages/_app.js +0 -5
- package/examples/react-next/pages/index.js +0 -97
- package/examples/react-next/postcss.config.mjs +0 -8
- package/examples/react-next/public/discord.svg +0 -8
- package/examples/react-next/public/favicon.ico +0 -0
- package/examples/react-next/public/file.svg +0 -1
- package/examples/react-next/public/logo.png +0 -0
- package/examples/react-next/public/next.svg +0 -1
- package/examples/react-next/shared/constants.js +0 -48
- package/examples/react-next/shared/cookies.js +0 -23
- package/examples/react-next/styles/globals.css +0 -24
- package/examples/react-next/tailwind.config.mjs +0 -17
- package/examples/serverLess/dist/index.23420cfa.js +0 -2973
- package/examples/serverLess/dist/index.23420cfa.js.map +0 -1
- package/examples/serverLess/dist/index.91b6cacc.js +0 -2
- package/examples/serverLess/dist/index.91b6cacc.js.map +0 -1
- package/examples/serverLess/dist/index.html +0 -1
- package/examples/serverLess/index.html +0 -39
- package/examples/serverLess/main.js +0 -113
- package/examples/serverLess/package.json +0 -18
- package/examples/serverLess/readme.md +0 -41
- package/examples/simple/index.html +0 -23
- package/examples/simple/simple.js +0 -80
- package/examples/taigua/index.html +0 -55
- package/examples/taigua/main.js +0 -490
- package/examples/tester.css +0 -74
- package/examples/vidromap/index.js +0 -20
- package/examples/vidromap/index.php +0 -111
- package/flows.md +0 -73
- package/helpers.md +0 -45
- package/src/index.js +0 -882
- package/src/shared/iframe-communicator.js +0 -18
- package/webpack.config.js +0 -22
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
var communicatorIframe1 = new VidroMaps.Communicator({'sessionToken':sessionToken,'id':'map-frame-one'});
|
|
2
|
-
var communicatorIframe2 = new VidroMaps.Communicator({'sessionToken':sessionToken,'id':'map-frame-two'});
|
|
3
|
-
|
|
4
|
-
var sessionToken = document.querySelector("#sessionToken");
|
|
5
|
-
var mapContainer = document.querySelector("#mapContainer");
|
|
6
|
-
var code1 = document.querySelector("#code1");
|
|
7
|
-
var code2 = document.querySelector("#code2");
|
|
8
|
-
var iframesContainer1 = document.querySelector("#iframes-container1");
|
|
9
|
-
var iframesContainer2 = document.querySelector("#iframes-container2");
|
|
10
|
-
|
|
11
|
-
var iframe = document.querySelector("#map-frame");
|
|
12
|
-
var host = document.querySelector("#overrideHost");
|
|
13
|
-
var btLoadIframe = document.querySelector("#btLoadIframe");
|
|
14
|
-
|
|
15
|
-
var btZoomIn1 = document.querySelector("#btZoomIn1");
|
|
16
|
-
var btZoomIn2 = document.querySelector("#btZoomIn2");
|
|
17
|
-
var btZoomOut1 = document.querySelector("#btZoomOut1");
|
|
18
|
-
var btZoomOut2 = document.querySelector("#btZoomOut2");
|
|
19
|
-
var btAddPoint1 = document.querySelector("#btAddPoint1");
|
|
20
|
-
var btAddPoint2 = document.querySelector("#btAddPoint2");
|
|
21
|
-
|
|
22
|
-
communicatorIframe1.on("loaded", function(data){
|
|
23
|
-
console.log("iframe 1 loaded",data);
|
|
24
|
-
});
|
|
25
|
-
communicatorIframe2.on("loaded", function(data){
|
|
26
|
-
console.log("iframe 2 loaded",data);
|
|
27
|
-
});
|
|
28
|
-
communicatorIframe2.on("coordinates", function(data){
|
|
29
|
-
console.info("map2 coordinates",data);
|
|
30
|
-
alert("map2 click")
|
|
31
|
-
});
|
|
32
|
-
communicatorIframe1.on("coordinates", function(data){
|
|
33
|
-
console.info("map1 coordinates",data);
|
|
34
|
-
alert("map1 click")
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
communicatorIframe1.on("geomAdded", function(data){
|
|
38
|
-
console.log("geomAdded to map1",data);
|
|
39
|
-
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
communicatorIframe2.on("geomAdded", function(data){
|
|
43
|
-
console.log("geomAdded to map2",data);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
//************** MAP EXAMPLE
|
|
47
|
-
|
|
48
|
-
if(btLoadIframe){
|
|
49
|
-
btLoadIframe.addEventListener("click", function (evt) {
|
|
50
|
-
if(code1.value!=""){
|
|
51
|
-
console.log('btLoadIframe',code1.value,typeof code1.value);
|
|
52
|
-
iframesContainer1.innerHTML = code1.value;
|
|
53
|
-
}
|
|
54
|
-
if(code2.value!=""){
|
|
55
|
-
console.log('btLoadIframe',code2.value,typeof code2.value);
|
|
56
|
-
iframesContainer2.innerHTML = code2.value;
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
btZoomIn1.addEventListener("click", function(){
|
|
62
|
-
return communicatorIframe1.ZoomIn();
|
|
63
|
-
});
|
|
64
|
-
btZoomIn2.addEventListener("click", function(){
|
|
65
|
-
return communicatorIframe2.ZoomIn();
|
|
66
|
-
});
|
|
67
|
-
btZoomOut1.addEventListener("click", function(){
|
|
68
|
-
communicatorIframe1.ZoomOut();
|
|
69
|
-
});
|
|
70
|
-
btZoomOut2.addEventListener("click", function(){
|
|
71
|
-
communicatorIframe2.ZoomOut();
|
|
72
|
-
});
|
|
73
|
-
if(btAddPoint1){
|
|
74
|
-
btAddPoint1.addEventListener("click", function(){
|
|
75
|
-
communicatorIframe1.AddGeom('Point');
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
if(btAddPoint2){
|
|
79
|
-
btAddPoint2.addEventListener("click", function(){
|
|
80
|
-
communicatorIframe2.AddGeom('Point');
|
|
81
|
-
});
|
|
82
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
<html>
|
|
2
|
-
<head>
|
|
3
|
-
<title>🛠️ MAP TESTER - Multiple Iframes</title>
|
|
4
|
-
<link rel="stylesheet" href="../tester.css"></link>
|
|
5
|
-
<link rel="icon" type="image/png" href="https://www.vidrosoftware.com/favicon/favicon-32x32.png" sizes="32x32" />
|
|
6
|
-
<link rel="icon" type="image/png" href="https://www.vidrosoftware.com/favicon/favicon-16x16.png" sizes="16x16" />
|
|
7
|
-
<style>
|
|
8
|
-
.iframes-container{
|
|
9
|
-
width: 320px;
|
|
10
|
-
height: 240;
|
|
11
|
-
}
|
|
12
|
-
</style>
|
|
13
|
-
</head>
|
|
14
|
-
<body>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<div class="form" id="userData">
|
|
19
|
-
<h1>Vidromap</h1>
|
|
20
|
-
|
|
21
|
-
<div id="sessionToken"></div>
|
|
22
|
-
<div>
|
|
23
|
-
Paste your first code here (Map 1):<br> <textarea name="code1" id="code1" rows="10" cols="100" placeholder=""><iframe id="map-frame-one" name="map-frame-one" width="100%" height="240" src="https://component.vidrosoftware.com?sessionToken=YOUR_SESSION_TOKEN&domId=map-frame-one"></iframe></textarea>
|
|
24
|
-
<br>
|
|
25
|
-
Paste your second code here (Map 2):<br> <textarea name="code2" id="code2" rows="10" cols="100" placeholder=""><iframe id="map-frame-two" name="map-frame-two" width="100%" height="240" src="https://component.vidrosoftware.com?sessionToken=YOUR_SESSION_TOKEN&domId=map-frame-two"></iframe></textarea>
|
|
26
|
-
</div>
|
|
27
|
-
<div>
|
|
28
|
-
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
<div>
|
|
32
|
-
<button id="btLoadIframe">Load Maps</button> -
|
|
33
|
-
</div>
|
|
34
|
-
<div id="Error_container"></div>
|
|
35
|
-
<div id="mapContainer">
|
|
36
|
-
<div id="iframes-container1" class="iframes-container"></div>
|
|
37
|
-
<h2>Map 1</h2>
|
|
38
|
-
<button id="btZoomIn1">Zoom In</button>
|
|
39
|
-
<button id="btZoomOut1">Zoom Out</button>
|
|
40
|
-
<button id="btAddPoint1">Add point map 1</button>
|
|
41
|
-
<div id="iframes-container2" class="iframes-container"></div>
|
|
42
|
-
<h2>Map 2</h2>
|
|
43
|
-
<button id="btZoomIn2">Zoom In</button>
|
|
44
|
-
<button id="btZoomOut2">Zoom Out</button>
|
|
45
|
-
<button id="btAddPoint2">Add point map 2</button>
|
|
46
|
-
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<script src="https://unpkg.com/@vidro/map-handler@1.0.7/dist/map-handler.js"></script>
|
|
50
|
-
<script src="./index.js"></script>
|
|
51
|
-
</body>
|
|
52
|
-
</html>
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
# Map Component React Integration
|
|
2
|
-
|
|
3
|
-
#### Feb, 2025
|
|
4
|
-
|
|
5
|
-
## Getting Started
|
|
6
|
-
|
|
7
|
-
This example is a basic mapComponent integration based in React 19 and Next.js
|
|
8
|
-
|
|
9
|
-
Requirements:
|
|
10
|
-
|
|
11
|
-
Node & npm ^19. We recommend using [nvm](https://github.com/nvm-sh/nvm) to manage multiple Node versions on a single server.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
>Install project
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
npm install
|
|
18
|
-
```
|
|
19
|
-
>Run
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm run dev
|
|
23
|
-
```
|
|
24
|
-
You can create an `.env` file with default values for the API URL, user, and password. Simply rename `.env.sample` to `.env`:
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
NEXT_PUBLIC_APIURL="https://your api url"
|
|
28
|
-
NEXT_PUBLIC_USER="your user"
|
|
29
|
-
NEXT_PUBLIC_PWD="your password"
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
This example uses [Tailwindcss](https://tailwindcss.com) for layout
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
## Example flow
|
|
36
|
-
|
|
37
|
-
1. **Signs in to the Maps API**
|
|
38
|
-
|
|
39
|
-
The API sign-in request returns an authentication token and a list of maps the user can access.
|
|
40
|
-
|
|
41
|
-
If the sign-in is successful, a dropdown with available maps will be populated.
|
|
42
|
-
|
|
43
|
-
2. **Select a map and click `Load map`**
|
|
44
|
-
|
|
45
|
-
The selected map will be loaded. 😉
|
|
46
|
-
|
|
47
|
-
## Project structure
|
|
48
|
-
|
|
49
|
-
- **pages**
|
|
50
|
-
- **index.js** is the main file
|
|
51
|
-
|
|
52
|
-
- **contexts**
|
|
53
|
-
- **auth.js** handles user's sign in and sign out
|
|
54
|
-
- **map.js** handles map info
|
|
55
|
-
- **messajes** handles communication with map component (mapHandler integration)
|
|
56
|
-
|
|
57
|
-
- **hooks**
|
|
58
|
-
- **useMapEvents** - custom hook for handling map events
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
- **components**
|
|
62
|
-
- **AuthComponent** component with auth
|
|
63
|
-
- **MapList** component with available maps
|
|
64
|
-
- **MapIframe** component with map iframe
|
|
65
|
-
- **MapButtons** component with map buttons
|
|
66
|
-
- **MapLayers** component with map layers, with toggle button
|
|
67
|
-
- **MapInfo** component for display map info
|
|
68
|
-
- **MapFilters** component for handle filters
|
|
69
|
-
|
|
70
|
-
- **shared**
|
|
71
|
-
- **constants.js** file with constants to minimize typos
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
## Step by step
|
|
75
|
-
* `components/SessionComponent` interacts with `contexts/auth.js` to handle sign-in and load the map list. Maps and the authentication token are stored in context state variables `projects` and `token`.
|
|
76
|
-
* If sign-in is successful, `components/SessionComponent` displays a dropdown with the map list and a `Load Map` button.
|
|
77
|
-
* When `Load Map` is clicked, it calls the `GetMap` method from `contexts/maps`. This sends a request to the maps API and retrieves the iframe URL along with the session token. The API response looks something like this:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
{
|
|
82
|
-
"message": {
|
|
83
|
-
"sessionToken": "eyJ0eXAiOiJKV1QiLC.... very long",
|
|
84
|
-
"iframe": "https:\/\/your.domain.com\/yourcomponent\/"
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
* `contexts/maps` sets context vars `map` and `sessionToken`. `map` will contain the url required by the iframe:
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
setSessionToken(message.essionToken);
|
|
93
|
-
setMap(
|
|
94
|
-
`${message.iframe}?sessionToken=${message.sessionToken}`
|
|
95
|
-
);
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
* `components/MapIframe` will render the iframe and start the mapHandler library:
|
|
99
|
-
|
|
100
|
-
```
|
|
101
|
-
useEffect(() => {
|
|
102
|
-
if (!sessionToken) return;
|
|
103
|
-
start(sessionToken); //starts communicator
|
|
104
|
-
}, [sessionToken]);
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
* `hooks/useMapEvents` listens to map events. When the map is loaded, a `loaded` event is emitted, and a context variable `mapReady` is set to `true`. This ensures that all child components recognize when the map is ready for interaction.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
if (!message) return;
|
|
113
|
-
switch (message.type) {
|
|
114
|
-
case MAP_EVENTS.LOADED:
|
|
115
|
-
if (message.what === "map") {
|
|
116
|
-
console.log("useMapEvents Map loaded and ready");
|
|
117
|
-
setMapReady(true);
|
|
118
|
-
}
|
|
119
|
-
setMessage(null);
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
}, [message]);
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Map is ready and buttons active!
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
## Map Events
|
|
130
|
-
|
|
131
|
-
The map emits several events. To avoid race conditions caused by concurrent events, we use a message queue.
|
|
132
|
-
|
|
133
|
-
In `contexts/messages.js` we manage this queue.
|
|
134
|
-
|
|
135
|
-
We have to state vars:
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
const [message, setMessage] = useState(null);
|
|
139
|
-
const [messageQueue, setMessageQueue] = useState([]);
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
We set listeners for the events we need:
|
|
144
|
-
|
|
145
|
-
```
|
|
146
|
-
useEffect(() => {
|
|
147
|
-
if (!communicator) return;
|
|
148
|
-
communicator.on(MAP_EVENTS.ZOOM_CHANGE, onMapEvent);
|
|
149
|
-
communicator.on(MAP_EVENTS.LOADED, onMapEvent);
|
|
150
|
-
|
|
151
|
-
return () => {
|
|
152
|
-
if (!communicator) return;
|
|
153
|
-
communicator.off(MAP_EVENTS.ZOOM_CHANGE, onMapEvent);
|
|
154
|
-
communicator.off(MAP_EVENTS.LOADED, onMapEvent);
|
|
155
|
-
|
|
156
|
-
setCommunicator(null);
|
|
157
|
-
};
|
|
158
|
-
}, [communicator, events]);
|
|
159
|
-
|
|
160
|
-
```
|
|
161
|
-
Each time an event is received we add the event to the queue
|
|
162
|
-
|
|
163
|
-
```
|
|
164
|
-
const onMapEvent = (data) => {
|
|
165
|
-
console.log(`onMapEvent`, { type: data.type, data });
|
|
166
|
-
setMessageQueue((prevQueue) => [...prevQueue, data]);
|
|
167
|
-
};
|
|
168
|
-
```
|
|
169
|
-
When `messageQueue` or `message` changes to `null`, we pick the next message in the queue `messageQueue[0]`
|
|
170
|
-
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
useEffect(() => {
|
|
174
|
-
if (message) return;
|
|
175
|
-
if (messageQueue.length === 0) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
setMessage(messageQueue[0]);
|
|
179
|
-
setMessageQueue((prevQueue) => {
|
|
180
|
-
return prevQueue.slice(1);
|
|
181
|
-
});
|
|
182
|
-
}, [messageQueue, message]);
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
In this project, all events are handled in `hooks/useMapEvents` , each event, when is handled sets `message` to `null` -> `setMessage(null)`, for example:
|
|
186
|
-
|
|
187
|
-
```
|
|
188
|
-
useEffect(() => {
|
|
189
|
-
if (!message) return;
|
|
190
|
-
switch (message.type) {
|
|
191
|
-
case MAP_EVENTS.LOADED:
|
|
192
|
-
if (message.what === "map") {
|
|
193
|
-
console.log("useMapEvents Map loaded and ready");
|
|
194
|
-
setMapReady(true);
|
|
195
|
-
}
|
|
196
|
-
setMessage(null);
|
|
197
|
-
break;
|
|
198
|
-
|
|
199
|
-
default:
|
|
200
|
-
setMessage(null);
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
}, [message, displayedLayers]);
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Adding elements to map
|
|
207
|
-
|
|
208
|
-
There's an example of how to add a point to map.
|
|
209
|
-
|
|
210
|
-
Button `Add point` starts the map component add point flow.
|
|
211
|
-
|
|
212
|
-
```
|
|
213
|
-
const { drawPoint } = useMessages();
|
|
214
|
-
<button
|
|
215
|
-
onClick={(e) => {
|
|
216
|
-
console.log("Draw point");
|
|
217
|
-
drawPoint({});
|
|
218
|
-
}}
|
|
219
|
-
>
|
|
220
|
-
Add point
|
|
221
|
-
</button>
|
|
222
|
-
```
|
|
223
|
-
When point is added, in `hooks/useMapEvents` we receive the event and we draw the geometry:
|
|
224
|
-
|
|
225
|
-
```
|
|
226
|
-
useEffect(() => {
|
|
227
|
-
if (!message) return;
|
|
228
|
-
switch (message.type) {
|
|
229
|
-
case MAP_EVENTS.GEOM_ADDED:
|
|
230
|
-
console.log("GeomAdded", message);
|
|
231
|
-
setCurrentMapAction(null);
|
|
232
|
-
//Highlight the added geom
|
|
233
|
-
Highlight(
|
|
234
|
-
{
|
|
235
|
-
feature_type: "HIGHLIGHT",
|
|
236
|
-
geom: message?.geom_astext,
|
|
237
|
-
},
|
|
238
|
-
2,
|
|
239
|
-
{
|
|
240
|
-
duration: 1500,
|
|
241
|
-
repeat: true,
|
|
242
|
-
},
|
|
243
|
-
0,
|
|
244
|
-
null
|
|
245
|
-
);
|
|
246
|
-
if (message?.geom_astext === null) {
|
|
247
|
-
setMessage(null);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
}, [message, displayedLayers]);
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
Check [Highlight method documentation](https://github.com/Vidro-Software-SL/maphandler?tab=readme-ov-file#higlight) to understand method params
|
|
254
|
-
|
|
255
|
-
## Filtering layers
|
|
256
|
-
|
|
257
|
-
In `components/MapFilters` there's an example of how to apply filters
|
|
258
|
-
|
|
259
|
-
Method `applyFilter`:
|
|
260
|
-
|
|
261
|
-
- Checks if there is an active layer selected.
|
|
262
|
-
- Constructs a filter object based on the selected layer and filter criteria.
|
|
263
|
-
- Sends the filter to the mapComponent to be applied on the map.
|
|
264
|
-
|
|
265
|
-
## Next.js
|
|
266
|
-
|
|
267
|
-
To learn more about Next.js, take a look at the following resources:
|
|
268
|
-
|
|
269
|
-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
|
270
|
-
- [Learn Next.js](https://nextjs.org/learn-pages-router) - an interactive Next.js tutorial.
|
|
271
|
-
|
|
272
|
-
## Tailwindcss
|
|
273
|
-
|
|
274
|
-
o learn more about Tailwindcss, take a look [https://tailwindcss.com](https://tailwindcss.com)
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
## Support
|
|
278
|
-
|
|
279
|
-
Join us in [Discord](https://discord.com/channels/1305257097843179642/1305257098313072714)
|
|
280
|
-
|
|
281
|
-

|
|
282
|
-
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { usePrint } from "@/contexts/print";
|
|
2
|
-
const { useMessages } = require("@/contexts/messages");
|
|
3
|
-
const { useState, useEffect } = require("react");
|
|
4
|
-
|
|
5
|
-
const PrintLayoutSelector = () => {
|
|
6
|
-
const { zoomToScale } = useMessages();
|
|
7
|
-
const { paperLayout, setPaperLayout, printEnabled } = usePrint();
|
|
8
|
-
const layouts = [
|
|
9
|
-
{ id: "landscape", val: "landscape", label: "landscape" },
|
|
10
|
-
{ id: "portrait", val: "portrait", label: "portrait" },
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
const [actualValue, setActualValue] = useState(
|
|
14
|
-
paperLayout ? paperLayout : "landscape"
|
|
15
|
-
);
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (!paperLayout) return;
|
|
18
|
-
const current = layouts.find((s) => s.val === paperLayout);
|
|
19
|
-
if (current) {
|
|
20
|
-
setActualValue(current.val);
|
|
21
|
-
} else {
|
|
22
|
-
setActualValue("landscape");
|
|
23
|
-
}
|
|
24
|
-
console.log("paperLayout", paperLayout);
|
|
25
|
-
}, [paperLayout]);
|
|
26
|
-
return (
|
|
27
|
-
<div className="mx-2 pt-2">
|
|
28
|
-
<label>Layout:</label>
|
|
29
|
-
<select
|
|
30
|
-
disabled={printEnabled}
|
|
31
|
-
value={actualValue}
|
|
32
|
-
onChange={(e) => {
|
|
33
|
-
const newVal = !isNaN(e.target.value)
|
|
34
|
-
? Number(e.target.value)
|
|
35
|
-
: e.target.value;
|
|
36
|
-
setActualValue(newVal);
|
|
37
|
-
setPaperLayout(newVal);
|
|
38
|
-
}}
|
|
39
|
-
>
|
|
40
|
-
{layouts.map((opt, index) => {
|
|
41
|
-
return (
|
|
42
|
-
<option key={`opt_layout_${index}`} value={opt.val}>
|
|
43
|
-
{opt.label}
|
|
44
|
-
</option>
|
|
45
|
-
);
|
|
46
|
-
})}
|
|
47
|
-
</select>
|
|
48
|
-
</div>
|
|
49
|
-
);
|
|
50
|
-
};
|
|
51
|
-
export default PrintLayoutSelector;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { usePrint } from "@/contexts/print";
|
|
2
|
-
const { useMessages } = require("@/contexts/messages");
|
|
3
|
-
const { useState, useEffect } = require("react");
|
|
4
|
-
|
|
5
|
-
const PrintPaperSizeSelector = () => {
|
|
6
|
-
const { zoomToScale } = useMessages();
|
|
7
|
-
const { paperSize, setPaperSize, printEnabled } = usePrint();
|
|
8
|
-
const sizes = [
|
|
9
|
-
{ id: "A4", val: "A4", label: "A4" },
|
|
10
|
-
{ id: "A3", val: "A3", label: "A3" },
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
const [actualValue, setActualValue] = useState(paperSize ? paperSize : "A4");
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (!paperSize) return;
|
|
16
|
-
const currentSize = sizes.find((s) => s.val === paperSize);
|
|
17
|
-
if (currentSize) {
|
|
18
|
-
setActualValue(currentSize.val);
|
|
19
|
-
} else {
|
|
20
|
-
setActualValue("A4");
|
|
21
|
-
}
|
|
22
|
-
console.log("paperSize", paperSize);
|
|
23
|
-
}, [paperSize]);
|
|
24
|
-
return (
|
|
25
|
-
<div className="mx-2 pt-2 text-xs">
|
|
26
|
-
<label>Paper size:</label>
|
|
27
|
-
<select
|
|
28
|
-
disabled={printEnabled}
|
|
29
|
-
value={actualValue}
|
|
30
|
-
onChange={(e) => {
|
|
31
|
-
const newVal = !isNaN(e.target.value)
|
|
32
|
-
? Number(e.target.value)
|
|
33
|
-
: e.target.value;
|
|
34
|
-
setActualValue(newVal);
|
|
35
|
-
setPaperSize(newVal);
|
|
36
|
-
}}
|
|
37
|
-
>
|
|
38
|
-
{sizes.map((opt, index) => {
|
|
39
|
-
return (
|
|
40
|
-
<option key={`opt_${index}`} value={opt.val}>
|
|
41
|
-
{opt.label}
|
|
42
|
-
</option>
|
|
43
|
-
);
|
|
44
|
-
})}
|
|
45
|
-
</select>
|
|
46
|
-
</div>
|
|
47
|
-
);
|
|
48
|
-
};
|
|
49
|
-
export default PrintPaperSizeSelector;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { useMaps } from "@/contexts/maps";
|
|
2
|
-
import { usePrint } from "@/contexts/print";
|
|
3
|
-
const { useMessages } = require("@/contexts/messages");
|
|
4
|
-
const { useState, useEffect } = require("react");
|
|
5
|
-
|
|
6
|
-
const PrintScaleSelector = () => {
|
|
7
|
-
const { zoomToScale } = useMessages();
|
|
8
|
-
const { mapScale, setMapScale } = useMaps();
|
|
9
|
-
const { printEnabled } = usePrint();
|
|
10
|
-
const scales = [
|
|
11
|
-
{ id: "1:100", val: "1:100", label: "1:100" },
|
|
12
|
-
{ id: "1:200", val: "1:200", label: "1:200" },
|
|
13
|
-
{ id: "1:500", val: "1:500", label: "1:500" },
|
|
14
|
-
{ id: "1:1000", val: "1:1000", label: "1:1000" },
|
|
15
|
-
{ id: "1:2000", val: "1:2000", label: "1:2000" },
|
|
16
|
-
{ id: "1:5000", val: "1:5000", label: "1:5000" },
|
|
17
|
-
{ id: "1:10000", val: "1:10000", label: "1:10000" },
|
|
18
|
-
{ id: "1:50000", val: "1:50000", label: "1:50000" },
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
const [actualValue, setActualValue] = useState(mapScale ? mapScale : "-1");
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (!mapScale) return;
|
|
24
|
-
const current = scales.find((s) => s.val === mapScale);
|
|
25
|
-
if (current) {
|
|
26
|
-
setActualValue(current.val);
|
|
27
|
-
} else {
|
|
28
|
-
setActualValue("-1");
|
|
29
|
-
}
|
|
30
|
-
console.log("mapScale", mapScale);
|
|
31
|
-
}, [mapScale]);
|
|
32
|
-
return (
|
|
33
|
-
<div className="mx-2 pt-2">
|
|
34
|
-
<label>Scale:</label>
|
|
35
|
-
<select
|
|
36
|
-
disabled={printEnabled}
|
|
37
|
-
value={actualValue}
|
|
38
|
-
onChange={(e) => {
|
|
39
|
-
const newVal = !isNaN(e.target.value)
|
|
40
|
-
? Number(e.target.value)
|
|
41
|
-
: e.target.value;
|
|
42
|
-
setActualValue(newVal);
|
|
43
|
-
zoomToScale(newVal);
|
|
44
|
-
setMapScale(newVal);
|
|
45
|
-
}}
|
|
46
|
-
>
|
|
47
|
-
<option key={`opt_select_scale`} value="-1">
|
|
48
|
-
Select scale...
|
|
49
|
-
</option>
|
|
50
|
-
{scales.map((opt, index) => {
|
|
51
|
-
return (
|
|
52
|
-
<option key={`opt_sca_${index}`} value={opt.val}>
|
|
53
|
-
{opt.label}
|
|
54
|
-
</option>
|
|
55
|
-
);
|
|
56
|
-
})}
|
|
57
|
-
</select>
|
|
58
|
-
</div>
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
export default PrintScaleSelector;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const { useMaps } = require("@/contexts/maps");
|
|
2
|
-
const { useMessages } = require("@/contexts/messages");
|
|
3
|
-
const { useState, useEffect } = require("react");
|
|
4
|
-
|
|
5
|
-
const ZoomToScaleButton = () => {
|
|
6
|
-
const { zoomToScale } = useMessages();
|
|
7
|
-
const { mapScale } = useMaps();
|
|
8
|
-
const scales = [
|
|
9
|
-
{ id: "1:100", val: "1:100", label: "1:100" },
|
|
10
|
-
{ id: "1:200", val: "1:200", label: "1:200" },
|
|
11
|
-
{ id: "1:500", val: "1:500", label: "1:500" },
|
|
12
|
-
{ id: "1:1000", val: "1:1000", label: "1:1000" },
|
|
13
|
-
{ id: "1:2000", val: "1:2000", label: "1:2000" },
|
|
14
|
-
{ id: "1:5000", val: "1:5000", label: "1:5000" },
|
|
15
|
-
{ id: "1:10000", val: "1:10000", label: "1:10000" },
|
|
16
|
-
{ id: "1:50000", val: "1:50000", label: "1:50000" },
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
const [actualValue, setActualValue] = useState(mapScale ? mapScale : "-1");
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
if (!mapScale) return;
|
|
22
|
-
const scale = scales.find((s) => s.val === mapScale);
|
|
23
|
-
if (scale) {
|
|
24
|
-
setActualValue(scale.val);
|
|
25
|
-
} else {
|
|
26
|
-
setActualValue("-1");
|
|
27
|
-
}
|
|
28
|
-
console.log("mapScale", mapScale, scale);
|
|
29
|
-
}, [mapScale]);
|
|
30
|
-
return (
|
|
31
|
-
<div className="mx-2 pt-2">
|
|
32
|
-
<label>Zoom to scale:</label>
|
|
33
|
-
<select
|
|
34
|
-
value={actualValue}
|
|
35
|
-
onChange={(e) => {
|
|
36
|
-
const newVal = !isNaN(e.target.value)
|
|
37
|
-
? Number(e.target.value)
|
|
38
|
-
: e.target.value;
|
|
39
|
-
setActualValue(newVal);
|
|
40
|
-
zoomToScale(newVal);
|
|
41
|
-
}}
|
|
42
|
-
>
|
|
43
|
-
<option key={`opt_select_scale`} value="-1">
|
|
44
|
-
Select scale...
|
|
45
|
-
</option>
|
|
46
|
-
{scales.map((opt, index) => {
|
|
47
|
-
return (
|
|
48
|
-
<option key={`opt_${index}`} value={opt.val}>
|
|
49
|
-
{opt.label}
|
|
50
|
-
</option>
|
|
51
|
-
);
|
|
52
|
-
})}
|
|
53
|
-
</select>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
export default ZoomToScaleButton;
|