TopoJSON Remapper
by Bart Kalisz
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>
<p>
This script takes a topojson and re-maps its geometries by given schema. <br />
If schema contains any names that don't match geometries or not all geometries have been matched it will generate "missing matches" array.
</p>
Babel + JSX
const config = {
srcTopoJsonUrl: "https://gist.githubusercontent.com/WunderBart/6a3c589643c1978fd5a9/raw/d5c98dc5be842e3b8272c96f13129ea8fbb6220e/world_by_iso_min_topo.json",
remapSchemeUrl: "https://gist.githubusercontent.com/WunderBart/bbea0b1bae6e91ad73d43a4dc27137b2/raw/aa61edf04b0271f7385e72764abfc4fd44ad613d/country_forums_by_region.json",
srcCollectionName: "worldByIso",
newCollectionName: "countryForumsByRegions",
};
class TopoJsonRemapper {
constructor(config) {
this.config = config;
}
go = () => {
if (!this.isDataReady()) {
this.fetchData().then(this.handleRemap);
} else {
this.handleRemap();
}
};
handleRemap = () => {
const remappedTopoJson = this.remap();
this.saveData({ remappedTopoJson });
this.openJson(remappedTopoJson);
console.log("Remapped TopoJson:", remappedTopoJson);
console.log("Missing matches:", this.data.missingMatches);
return remappedTopoJson;
};
fetchSrcTopoJson = url => fetch(url || this.config.srcTopoJsonUrl)
.then(response => response.json())
.then(json => { this.saveData({ srcTopoJson: json }) })
.catch(error => console.log("fetchTopoJson error:", error));
fetchRemapScheme = url => fetch(url || this.config.remapSchemeUrl)
.then(response => response.json())
.then(json => { this.saveData({ remapScheme: json }) })
.catch(error => console.log("fetchRemapScheme error:", error));
fetchData = () => Promise.all([this.fetchSrcTopoJson(), this.fetchRemapScheme()]);
collectArcs = idArray => {
const { config, data } = this;
const { geometries } = data.srcTopoJson.objects[config.srcCollectionName]
let tmpArcs = [];
let tmpIdArray = _.map(idArray, this.normalizeText)
geometries.forEach(geo => {
const geoName = this.normalizeText(geo.properties.name);
if (_.includes(tmpIdArray, geoName)) {
tmpArcs = _.concat(tmpArcs, geo.type === "Polygon" ? [geo.arcs] : geo.arcs);
tmpIdArray = _.pull(tmpIdArray, geoName);
}
...