从 Wikidata 获取 geojson 数据

我请求维基数据实体并获取它们的 geoshape property (P3896)

例如 (try it):

SELECT ?item ?itemLabel ?geoshape ?geoshapelabel
WHERE
{
  VALUES ?item { wd:Q142 }
  ?item wdt:P3896 ?geoshape.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

所以我得到一个网址:http://commons.wikimedia.org/data/main/Data:France.map

我尝试使用 Javascript 获取数据:

  • fetch('http://commons.wikimedia.org/data/main/Data:France.map?origin=*')
  • fetch('https://commons.wikimedia.org/w/index.php?title=Data:France.map&action=raw&origin=*')

但是由于 CORS 政策我出错了:

请求中不存在“access-control-allow-origin”标头 资源。

有没有办法从 Web 应用程序的 Wikidata 中获取 geojson 数据?

sunshine7993 回答:从 Wikidata 获取 geojson 数据

根据@Pascalo我们可以使用

fetch('https://commons.wikimedia.org/w/api.php?action=query&prop=revisions&rvslots=*&rvprop=content&format=json&titles=Data:France.map&origin=*')

从 Wikidata 获取 geojson 数据的完整 JS 解决方案如下:

class SPARQLQueryDispatcher {
  constructor(endpoint) {
    this.endpoint = endpoint;
  }
  query(sparqlQuery,simplify = true) {
    const fullUrl = this.endpoint + "?query=" + encodeURIComponent(sparqlQuery);
    const headers = {
      Accept: "application/sparql-results+json"
    };
    return fetch(fullUrl,{
        headers
      })
      .then(body => body.json())
      .then(data => (simplify ? this.simplify(data) : data));
  }
  simplify(data) {
    const bindings = data.results.bindings;
    return bindings.map(binding => {
      Object.keys(binding).forEach(function(key,index) {
        binding[key] = binding[key].value;
      });
      return binding;
    });
  }
}

function buildQuery(ids) {
  const wds = ids.map(id => `wd:${id}`).join(" ");
  return `
SELECT ?item ?itemLabel ?geoshape ?geoshapeLabel
WHERE
{
  VALUES ?item { ${wds} }
  ?item wdt:P3896 ?geoshape.
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
`;
}

function fetchGeojson(rows) {
  const titles = rows
    .filter(r => r.geoshape)
    .map(r => r.geoshape.split("/data/main/").pop())
    .join("|");
  return fetch(`https://commons.wikimedia.org/w/api.php?action=query&prop=revisions&rvslots=*&rvprop=content&format=json&titles=${titles}&origin=*`)
    .then(r => r.json())
    .then(r => Object.values(r.query.pages))
    .then(r => r.map(r => JSON.parse(r.revisions[0].slots.main["*"]).data));
}

const queryDispatcher = new SPARQLQueryDispatcher("https://query.wikidata.org/sparql");
const query = buildQuery(["Q90"]); // Q90 = Paris

queryDispatcher
  .query(query)
  .then(fetchGeojson)
  .then(console.log);

本文链接:https://www.f2er.com/676094.html

大家都在问