PageSourceSearch

https://www.geoboundaries.org/assets/js/internalData.js

js geoboundaries.org collected 2026-09-24 09:24:29 UTC 11,042 bytes, 315 lines download raw bytes

1
2var GITBRANCH = 'stable'; // metadata and source data is read from this branch
3
4function getZipFileContent(zipdata, name) {
5    console.log('unzipping...');
6    var zip = new JSZip(zipdata);
7    var topodata = zip.file(name).asText();
8    console.log('unzipped '+name); //+' '+topodata.substring(0,1000));
9    return topodata;
10};
11
12function Topoj2Geoj(topoj) {
13    function transformArcs(arcs, scale, translate) {
14        for (let i = 0, ii = arcs.length; i < ii; ++i) {
15            transformArc(arcs[i], scale, translate);
16        }
17    };
18    function transformArc(arc, scale, translate) {
19        let x = 0;
20        let y = 0;
21        for (let i = 0, ii = arc.length; i < ii; ++i) {
22            const vertex = arc[i];
23            x += vertex[0];
24            y += vertex[1];
25            vertex[0] = x;
26            vertex[1] = y;
27            transformVertex(vertex, scale, translate);
28        }
29    };
30    function transformVertex(vertex, scale, translate) {
31        vertex[0] = vertex[0] * scale[0] + translate[0];
32        vertex[1] = vertex[1] * scale[1] + translate[1];
33    };
34    function concatenateArcs(indices, arcs) {
35        const coordinates = [];
36        let index, arc;
37        for (let i = 0, ii = indices.length; i < ii; ++i) {
38          index = indices[i];
39          if (i > 0) {
40            // splicing together arcs, discard last point
41            coordinates.pop();
42          }
43          if (index >= 0) {
44            // forward arc
45            arc = arcs[index];
46          } else {
47            // reverse arc
48            arc = arcs[~index].slice().reverse();
49          }
50          // THIS IS THE FIX
51          //coordinates.push.apply(coordinates, arc);
52          for (p of arc) {
53            coordinates.push(p);
54          };
55        }
56        // provide fresh copies of coordinate arrays
57        /*
58        for (let j = 0, jj = coordinates.length; j < jj; ++j) {
59          coordinates[j] = coordinates[j].slice();
60        }
61        */
62        return coordinates;
63    };
64    function readPolygonGeometry(object, arcs) {
65        const coordinates = [];
66        for (let i = 0, ii = object['arcs'].length; i < ii; ++i) {
67          coordinates[i] = concatenateArcs(object['arcs'][i], arcs);
68        }
69        return coordinates; //new Polygon(coordinates);
70    };
71    function readMultiPolygonGeometry(object, arcs) {
72        const coordinates = [];
73        for (let i = 0, ii = object['arcs'].length; i < ii; ++i) {
74          // for each polygon
75          const polyArray = object['arcs'][i];
76          const ringCoords = [];
77          for (let j = 0, jj = polyArray.length; j < jj; ++j) {
78            // for each ring
79            ringCoords[j] = concatenateArcs(polyArray[j], arcs);
80          }
81          coordinates[i] = ringCoords;
82        }
83        return coordinates; //new MultiPolygon(coordinates);
84    };
85    const GEOMETRY_READERS = {
86        //'Point': readPointGeometry,
87        //'LineString': readLineStringGeometry,
88        'Polygon': readPolygonGeometry,
89        //'MultiPoint': readMultiPointGeometry,
90        //'MultiLineString': readMultiLineStringGeometry,
91        'MultiPolygon': readMultiPolygonGeometry,
92    };
93    // transform quantized coordinates
94    var transform = topoj['transform']
95    if (transform) {
96        scale = transform['scale'];
97        translate = transform['translate'];
98        transformArcs(topoj['arcs'], scale, translate);
99    };
100    // make geojson
101    var layers = Object.keys(topoj.objects);
102    var lyr = layers[0];
103    var features = [];
104    for (obj of topoj.objects[lyr].geometries) {
105        var reader = GEOMETRY_READERS[obj.type];
106        var coords = reader(obj, topoj.arcs);
107        var geom = {'type':obj.type, 'coordinates':coords};
108        var feat = {'type':'Feature',
109                    'geometry':geom,
110                    'properties':obj.properties};
111        //console.log(feat);
112        features.push(feat);
113    };
114    var geoj = {'type':'FeatureCollection',
115                'features':features};
116    return geoj;
117};
118
119/*
120function fixTopoJSON(topoj) {
121    console.log('truncating...');
122    for (i=0; i<topoj.arcs.length; i++) {
123        // truncate to first 100,000 points
124        arc = topoj.arcs[i];
125        if (arc.length > 100*1000) {
126            var newArc = arc.slice(0, 100*1000);
127            // add the last point
128            var lastpoint = arc[arc.length-1];
129            newArc.push(lastpoint);
130            topoj.arcs[i] = newArc;
131        };
132        //console.log(topoj.arcs[i].length);
133    };
134    console.log('done truncating');
135};
136*/
137
138function loadFromTopoJSON(source, topoj) {
139    //alert('reading features...');
140    
141    // TEMPORARY: 
142    // manually convert to geojson and redirect to geojson loading
143    // fixes call stack error inherent in ol.format.TopoJSON reader
144    console.log('topoj 2 geoj...')
145    var geoj = Topoj2Geoj(topoj);
146    console.log('geoj loaded');
147    // redirect to geojson loader
148    loadFromGeoJSON(source, geoj);
149    // exit early
150    return
151
152    // standard openlayers approach
153    var format = new ol.format.TopoJSON({});
154
155    // debug explore arc lengths as a cause of maximum call stack error
156    //console.log('topo objects '+topoj.objects.data.geometries.length)
157    //console.log('topo arcs '+topoj.arcs.length)
158    /*
159    var layers = Object.keys(topoj.objects);
160    var lyr = layers[0];
161    for (geom of topoj.objects[lyr].geometries) {
162        var polys = geom.arcs;
163        if (geom.type == 'Polygon') {
164            polys = [geom.arcs]
165        };
166        //console.log(polys)
167        var coords = [];
168        var count = 0;
169        for (poly of polys) {
170            for (ring of poly) {
171                for (i of ring) {
172                    i = Math.abs(i);
173                    arc = topoj.arcs[i];
174                    //console.log('arc '+i+' of '+topoj.arcs.length)
175                    console.log(coords.length+' + '+arc.length)
176                    coords.push.apply(coords, arc);
177                    count += arc.length;
178                };
179            };
180        };
181        console.log('obj point count '+count)
182    };
183    */
184    //console.log('topo arc1 '+topoj.arcs[0].length)
185    //console.log('topo obj1 '+JSON.stringify(topoj.objects.data.geometries[0]))
186    //console.log('topo obj1 arcs '+topoj.objects.data.geometries[0].arcs.length)
187    //console.log('topo obj1 total points '+count)
188
189    // read the features
190    //console.log('loading features...')
191    var features = format.readFeatures(topoj, {
192                                                dataProjection: 'EPSG:4326',
193                                                featureProjection: 'EPSG:3857'
194                                            }
195                                        );
196    //console.log('features loaded');
197    // set ids
198    var i = 1;
199    for (feat of features) {
200        feat.setId(i);
201        i++;
202    };
203    // add
204    //console.log('adding features...');
205    source.addFeatures(features);
206    //console.log('features added');
207};
208
209function loadFromGeoJSON(source, geoj) {
210    //alert('reading features...');
211    var format = new ol.format.GeoJSON({});
212    var allFeatures = format.readFeatures(geoj, {
213                                                dataProjection: 'EPSG:4326',
214                                                featureProjection: 'EPSG:3857'
215                                            }
216                                        );
217    //alert(features.length + ' features fetched');
218    // set ids
219    var i = 1;
220    var features = [];
221    for (feat of allFeatures) {
222        if (feat.getGeometry() == null) {
223            // ignore null geoms
224            continue;
225        };
226        features.push(feat);
227        feat.setId(i);
228        i++;
229    };
230    // add
231    source.addFeatures(features);
232    //alert('features added');
233};
234
235function loadGeoContrastSource(source, iso, level, sourceName) {
236    // get geoContrast metadata
237    var metadata = geoContrastMetadata;
238    // find the data url from the corresponding entry in the meta table
239    for (var i = 1; i < metadata.length; i++) {
240        var row = metadata[i];
241        if (row.length <= 1) {
242            // ignore empty rows
243            i++;
244            continue;
245        };
246        var currentIso = row.boundaryISO;
247        var currentLevel = row.boundaryType;
248        var currentSource = row['boundarySource-1'];
249        if ((sourceName == currentSource) & (iso == currentIso) & (level == currentLevel)) {
250            // get the data url from the table entry
251            var apiUrl = row.apiURL;
252            break;
253        };
254    };
255    // manually load topojson from url
256    if (apiUrl.endsWith('.topojson')) {
257        fetch(apiUrl)
258            .then(resp => resp.json())
259            .then(out => loadFromTopoJSON(source, out))
260            //.catch(err => alert('Failed to load data from '+apiUrl+'. Please choose another source. Error: '+JSON.stringify(err)));
261    } else if (apiUrl.endsWith('.zip')) {
262        if (GITBRANCH != 'stable') {
263            // HACKY FIX:
264            // all metadata api urls are set to stable
265            // until this is changed, hacky replace with branch name for now
266            apiUrl = apiUrl.replace('/geoContrast/stable/', '/geoContrast/'+GITBRANCH+'/');
267        };
268        var splitUrl = apiUrl.split('/');
269        var extractName = splitUrl[splitUrl.length-1].replace('.zip','');
270        if (extractName.endsWith('.topojson')) {
271            /*
272            JSZipUtils.getBinaryContent(apiUrl, function(err, data) {
273                console.log(err);
274                console.log(data);
275                topoj = JSON.parse(getZipFileContent(data, extractName));
276                loadFromTopoJSON(source, topoj);
277            })
278            */
279            fetch(apiUrl)
280                .then(resp => resp.arrayBuffer() )
281                .then(out => loadFromTopoJSON( source, JSON.parse(getZipFileContent(out, extractName))) )
282                //.catch(err => alert('Failed to load data from '+apiUrl+'. Please choose another source. Error: '+JSON.stringify(err)));
283        };
284    };
285};
286
287function loadGeoContrastMetadata(onSuccess) {
288    // fetch metadata
289    // determine url of metadata csv
290    url = 'https://raw.githubusercontent.com/wmgeolab/geoContrast/18c5aff53ae64b38803b01786da78b63344c5809/releaseData/geoContrast-meta.csv';
291    if (GITBRANCH != 'stable') {
292        // HACKY FIX:
293        // all metadata api urls are set to stable
294        // until this is changed, hacky replace with branch name for now
295        url = url.replace('/geoContrast/stable/', '/geoContrast/'+GITBRANCH+'/');
296    };
297    // define error and success
298    function error (err, file, inputElem, reason) {
299        alert('geoContrast metadata csv failed to load: '+url);
300    };
301    function success (result) {
302        //alert('load success');
303        // process csv data using custom function
304        onSuccess(result['data']);
305    };
306    // parse
307    Papa.parse(url,
308                {'download':true,
309                'header':true,
310                'complete':success,
311                'error':error,
312                }
313    );
314};
315

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.