WMS 迭代 getFeatureInfo URL 数组以获取响应随机化接收值的顺序
WMS Iterating through an Array of getFeatureInfo URLs to fetch the response randomizes the order of received values
背景:
使用 Openlayers 和 Geoserver,我得到了一个如下图所示的 WMS 层,它有两个不同的视图参数,可以分别取 5 和 7 个值。结合这两者,我总共可以获得 35 个不同的值。我想实现一个函数,当您单击一个国家/地区时,用所有这些值(7 行,5 列)填充 table。
WMS Layer
为此,我首先生成一个包含 35 个唯一 getFeatureInfo 网址的数组,如下所示 http://localhost:8080/geoserver/abschluss/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=abschluss&LAYERS=abschluss&TILED=true&CRS=EPSG%3A3857&VIEWPARAMS=year%3A2000%3Bcode%3A1&INFO_FORMAT=application%2Fjson&I=106&J=72&WIDTH=256&HEIGHT=256&STYLES=&BBOX=0%2C5009377.085697312%2C2504688.5428486555 %2C7514065.628545968 使用 for 循环和 url.replace 函数。然而,这不是问题。
let value = [];
for (i = 0; i<5; i++) {
const url = urlArray[i];
if (url) {
fetch(url)
.then((response) => response.text())
.then((jsonResponse) => {
const jsonObject = JSON.parse(jsonResponse);
value.push(jsonObject.features[0].properties.year);
});
}
}
有了这个,我想遍历我的 urlArray 的前 5 个元素,将响应作为 JSON 对象获取,提取所需的值并将它们写入一个新数组,然后用于在 HTML table 中填写一行。
使用 console.log(值);我可以看到这确实给了我想要的值,但是顺序似乎是随机的。每次我点击国家时,顺序都会完全改变。
为什么会发生这种情况,我该怎么做才能解决这个问题?
为了让您更好地理解,我将整个函数按原样包含在内:
map.on('singleclick', function (evt) {
document.getElementById('gfi').innerHTML = '';
const viewResolution = /** @type {number} */ (view.getResolution());
var url = sourceValues.getFeatureInfoUrl(
evt.coordinate,
viewResolution,
'EPSG:3857',
{'INFO_FORMAT': 'application/json'},
{'VIEWPARAMS': 'code:1;year:1990'}
);
let yearArray = [1995,2000,2005,2010,2015];
urlArray = [];
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 1, 'code%3A' + 2);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 2, 'code%3A' + 3);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 3, 'code%3A' + 4);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 4, 'code%3A' + 5);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 5, 'code%3A' + 6);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 6, 'code%3A' + 7);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990).replace('code%3A' + 7, 'code%3A' + 1);;
console.log(urlArray);
let value = [];
for (i = 0; i<5; i++) {
const url = urlArray[i];
if (url) {
fetch(url)
.then((response) => response.text())
.then((jsonResponse) => {
const jsonObject = JSON.parse(jsonResponse);
value.push(jsonObject.features[0].properties.year);
});
}
}
console.log(value);
});
fetch
是一个异步 Promise,接收响应的顺序将决定服务器处理请求的速度,这可能取决于查询和数据的复杂性。要以固定顺序处理响应,请使用 Promise.all
参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
let value = [];
let fetches = [];
for (i = 0; i<5; i++) {
const url = urlArray[i];
if (url) {
fetches.push(fetch(url));
}
}
Promise.all(fetches).then((responses) => {
responses.forEach((response) => {
...
});
});
好的,所以我找到了解决方案here:
let value = [];
const fetchAll = async (urls) => {
const res = await Promise.all(urls.map(u => fetch(u)))
const jsons = await Promise.all(res.map(r => r.json()))
for (i = 0; i< jsons.length; i++) {
const val = jsons[i].features[0].properties.year;
value.push(val);
}
}
fetchAll(urlArray);
背景: 使用 Openlayers 和 Geoserver,我得到了一个如下图所示的 WMS 层,它有两个不同的视图参数,可以分别取 5 和 7 个值。结合这两者,我总共可以获得 35 个不同的值。我想实现一个函数,当您单击一个国家/地区时,用所有这些值(7 行,5 列)填充 table。 WMS Layer
为此,我首先生成一个包含 35 个唯一 getFeatureInfo 网址的数组,如下所示 http://localhost:8080/geoserver/abschluss/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=abschluss&LAYERS=abschluss&TILED=true&CRS=EPSG%3A3857&VIEWPARAMS=year%3A2000%3Bcode%3A1&INFO_FORMAT=application%2Fjson&I=106&J=72&WIDTH=256&HEIGHT=256&STYLES=&BBOX=0%2C5009377.085697312%2C2504688.5428486555 %2C7514065.628545968 使用 for 循环和 url.replace 函数。然而,这不是问题。
let value = [];
for (i = 0; i<5; i++) {
const url = urlArray[i];
if (url) {
fetch(url)
.then((response) => response.text())
.then((jsonResponse) => {
const jsonObject = JSON.parse(jsonResponse);
value.push(jsonObject.features[0].properties.year);
});
}
}
有了这个,我想遍历我的 urlArray 的前 5 个元素,将响应作为 JSON 对象获取,提取所需的值并将它们写入一个新数组,然后用于在 HTML table 中填写一行。 使用 console.log(值);我可以看到这确实给了我想要的值,但是顺序似乎是随机的。每次我点击国家时,顺序都会完全改变。 为什么会发生这种情况,我该怎么做才能解决这个问题?
为了让您更好地理解,我将整个函数按原样包含在内:
map.on('singleclick', function (evt) {
document.getElementById('gfi').innerHTML = '';
const viewResolution = /** @type {number} */ (view.getResolution());
var url = sourceValues.getFeatureInfoUrl(
evt.coordinate,
viewResolution,
'EPSG:3857',
{'INFO_FORMAT': 'application/json'},
{'VIEWPARAMS': 'code:1;year:1990'}
);
let yearArray = [1995,2000,2005,2010,2015];
urlArray = [];
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 1, 'code%3A' + 2);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 2, 'code%3A' + 3);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 3, 'code%3A' + 4);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 4, 'code%3A' + 5);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 5, 'code%3A' + 6);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990);
for(let i = 0; i < yearArray.length; i++) {
year = yearArray[i];
url = url.replace('year%3A' + (year-5), 'year%3A' + year).replace('code%3A' + 6, 'code%3A' + 7);
urlArray.push(url);
}
url = url.replace('year%3A' + (2015), 'year%3A' + 1990).replace('code%3A' + 7, 'code%3A' + 1);;
console.log(urlArray);
let value = [];
for (i = 0; i<5; i++) {
const url = urlArray[i];
if (url) {
fetch(url)
.then((response) => response.text())
.then((jsonResponse) => {
const jsonObject = JSON.parse(jsonResponse);
value.push(jsonObject.features[0].properties.year);
});
}
}
console.log(value);
});
fetch
是一个异步 Promise,接收响应的顺序将决定服务器处理请求的速度,这可能取决于查询和数据的复杂性。要以固定顺序处理响应,请使用 Promise.all
参见 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
let value = [];
let fetches = [];
for (i = 0; i<5; i++) {
const url = urlArray[i];
if (url) {
fetches.push(fetch(url));
}
}
Promise.all(fetches).then((responses) => {
responses.forEach((response) => {
...
});
});
好的,所以我找到了解决方案here:
let value = [];
const fetchAll = async (urls) => {
const res = await Promise.all(urls.map(u => fetch(u)))
const jsons = await Promise.all(res.map(r => r.json()))
for (i = 0; i< jsons.length; i++) {
const val = jsons[i].features[0].properties.year;
value.push(val);
}
}
fetchAll(urlArray);