]>
Wikimedia Canada | Git repositories - eccc_map.git/blob - eccc_map.js
2 * eccc_map - Tool to show a map of ECCC stations and generate a list based on
3 * a polygon drawn by user.
4 * Copyright (C) 2020 Pierre Choffet
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 // Download station inventory as distributed with eccc_map since we cannot
22 // get the upstream one that is on a ftp server.
23 // Original URL: ftp://client_climate@ftp.tor.ec.gc.ca/Pub/Get_More_Data_Plus_de_donnees/Station Inventory EN.csv
24 const csv_url
= 'Station Inventory EN.csv';
25 const map
= L
.map('map').setView([70.44,-88.07], 4);
26 const draws
= new L
.FeatureGroup();
27 const cluster
= L
.markerClusterGroup();
28 const icon
= L
.icon({iconUrl: 'leaflet/marker-icon.png', shadowUrl: 'leaflet/marker-shadow.png'});
29 var markers_selected
= [];
31 L
.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
33 attribution: '<a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors',
41 const draw_control
= new L
.Control
.Draw({
58 map
.on(L
.Draw
.Event
.DRAWSTART
, function (event
) {
62 map
.on(L
.Draw
.Event
.CREATED
, function (event
) {
63 const layer
= event
.layer
;
64 const polygon_latlngs
= layer
.getLatLngs();
66 draws
.addLayer(layer
);
68 markers_selected
= [];
70 cluster
.eachLayer(function(e
) {
71 if (e
instanceof L
.Marker
) {
73 const marker_lat
= e
.getLatLng().lat
;
74 const marker_lon
= e
.getLatLng().lng
;
76 for (let latlngs_browse
= 0; latlngs_browse
< polygon_latlngs
.length
; ++latlngs_browse
){
77 let points
= polygon_latlngs
[latlngs_browse
];
79 for (let i
= 0, j
= points
.length
- 1; i
< points
.length
; j
= i
++) {
80 let xi
= points
[i
].lat
;
81 let yi
= points
[i
].lng
;
82 let xj
= points
[j
].lat
;
83 let yj
= points
[j
].lng
;
85 let intersect
= ((yi
> marker_lon
) != (yj
> marker_lon
)) && (marker_lat
< (xj
- xi
) * (marker_lon
- yi
) / (yj
- yi
) + xi
);
92 markers_selected
.push(e
);
100 map
.addControl(draw_control
);
102 // Add custom draw button click event
103 let button
= document
.getElementById('draw-polygon');
104 button
.addEventListener('click', function() {draw_control
._toolbars
.draw
._modes
.polygon
.handler
.enable();});
106 // Fetch csv file, read it line by line
107 async
function readStationsEntries(callback
) {
112 return response
.body
.getReader();
117 function readChunk({done
, value
}) {
121 const decoder
= new TextDecoder();
122 text
+= decoder
.decode(value
);
124 return reader
.read().then(readChunk
);
128 const text_split
= text
.split("\n");
129 const lines_count
= text_split
.length
;
130 let lines_browse
= 0;
132 // Consume csv header
133 for (; lines_browse
< lines_count
; ++lines_browse
) {
134 if (text_split
[lines_browse
].startsWith('"Name",'))
139 // Read stations rows
140 for (; lines_browse
< lines_count
- 1; ++lines_browse
) {
141 // To keep code simple, we expect CSV entries to be surrounded by
142 // two '"' characters and containing no additional one in their values.
143 // We just count occurences of '"' per line to ensure sanity.
144 if (text_split
[lines_browse
].split('"').length
!= 39) {
145 console
.error('Illegal station entry: line '+(lines_browse
+1));
149 const entry
= text_split
[lines_browse
].split(',');
150 const name
= entry
[0].replaceAll('"', '');
151 const cid
= entry
[2].replaceAll('"', '');
152 const lat
= entry
[6].replaceAll('"', '');
153 const lon
= entry
[7].replaceAll('"', '');
155 const marker
= L
.marker([lat
, lon
], {icon: icon
, cid: cid
});
156 marker
.bindPopup('<h1>'+name
+'</h1><h2>'+cid
+'</h2>');
157 marker
.addTo(cluster
);
160 map
.addLayer(cluster
);
167 function updateOutput() {
169 for (let markers_browse
= 0; markers_browse
< markers_selected
.length
; ++markers_browse
) {
170 if (markers_browse
!= 0)
171 output
+= document
.getElementById('separator').value
;
173 output
+= document
.getElementById('pattern').value
.replace('{cid}', markers_selected
[markers_browse
].options
.cid
);
175 document
.getElementById('output').value
= output
;
178 readStationsEntries();
180 // Add events in settings fields
181 document
.getElementById('pattern').addEventListener('blur', updateOutput
);
182 document
.getElementById('separator').addEventListener('blur', updateOutput
);