You've already forked wakapi-readme-stats
Bar graph added.
This commit is contained in:
13
node_modules/topojson-client/LICENSE
generated
vendored
Normal file
13
node_modules/topojson-client/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Copyright 2012-2019 Michael Bostock
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
242
node_modules/topojson-client/README.md
generated
vendored
Normal file
242
node_modules/topojson-client/README.md
generated
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
# TopoJSON Client
|
||||
|
||||
The **topojson-client** module provides tools for manipulating [TopoJSON](https://github.com/topojson/topojson), such as to [merge shapes](#merge) or [quantize coordinates](#quantize), and for converting back to [GeoJSON](#feature) for rendering with standard tools such as [d3.geoPath](https://github.com/d3/d3-geo/blob/master/README.md#geoPath). For example, [bl.ocks.org/3783604](https://bl.ocks.org/mbostock/3783604):
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<canvas width="960" height="600"></canvas>
|
||||
<script src="https://d3js.org/d3.v4.min.js"></script>
|
||||
<script src="https://unpkg.com/topojson-client@3"></script>
|
||||
<script>
|
||||
|
||||
var context = d3.select("canvas").node().getContext("2d"),
|
||||
path = d3.geoPath().context(context);
|
||||
|
||||
d3.json("https://d3js.org/us-10m.v1.json", function(error, us) {
|
||||
if (error) throw error;
|
||||
|
||||
context.beginPath();
|
||||
path(topojson.mesh(us));
|
||||
context.stroke();
|
||||
});
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
## Installing
|
||||
|
||||
If you use NPM, `npm install topojson-client`. Otherwise, download the [latest release](https://github.com/topojson/topojson-client/releases/latest). You can also load directly from [UNPKG](https://unpkg.com) as a [standalone library](https://unpkg.com/topojson-client@3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `topojson` global is exported:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/topojson-client@3"></script>
|
||||
<script>
|
||||
|
||||
var feature = topojson.feature(topology, "foo");
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
The TopoJSON client API is implemented using ES2015 modules. In compatible environments, you can import the library as a namespace, like so:
|
||||
|
||||
```js
|
||||
import * as topojson from "topojson-client";
|
||||
```
|
||||
|
||||
[Try topojson-client in your browser.](https://runkit.com/npm/topojson-client)
|
||||
|
||||
# API Reference
|
||||
|
||||
<a name="feature" href="#feature">#</a> topojson.<b>feature</b>(<i>topology</i>, <i>object</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/feature.js "Source")
|
||||
|
||||
Returns the GeoJSON Feature or FeatureCollection for the specified *object* in the given *topology*. If the specified object is a string, it is treated as *topology*.objects[*object*]. Then, if the object is a GeometryCollection, a FeatureCollection is returned, and each geometry in the collection is mapped to a Feature. Otherwise, a Feature is returned. The returned feature is a shallow copy of the source *object*: they may share identifiers, bounding boxes, properties and coordinates.
|
||||
|
||||
Some examples:
|
||||
|
||||
* A point is mapped to a feature with a geometry object of type “Point”.
|
||||
* Likewise for line strings, polygons, and other simple geometries.
|
||||
* A null geometry object (of type null in TopoJSON) is mapped to a feature with a null geometry object.
|
||||
* A geometry collection of points is mapped to a feature collection of features, each with a point geometry.
|
||||
* A geometry collection of geometry collections is mapped to a feature collection of features, each with a geometry collection.
|
||||
|
||||
See [feature-test.js](https://github.com/topojson/topojson-client/blob/master/test/feature-test.js) for more examples.
|
||||
|
||||
<a name="merge" href="#merge">#</a> topojson.<b>merge</b>(<i>topology</i>, <i>objects</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/merge.js#L5 "Source")
|
||||
|
||||
Returns the GeoJSON MultiPolygon geometry object representing the union for the specified array of Polygon and MultiPolygon *objects* in the given *topology*. Interior borders shared by adjacent polygons are removed. See [Merging States](https://bl.ocks.org/mbostock/5416405) for an example. The returned geometry is a shallow copy of the source *object*: they may share coordinates.
|
||||
|
||||
<a name="mergeArcs" href="#mergeArcs">#</a> topojson.<b>mergeArcs</b>(<i>topology</i>, <i>objects</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/merge.js#L9 "Source")
|
||||
|
||||
Equivalent to [topojson.merge](#merge), but returns TopoJSON rather than GeoJSON. The returned geometry is a shallow copy of the source *object*: they may share coordinates.
|
||||
|
||||
<a name="mesh" href="#mesh">#</a> topojson.<b>mesh</b>(<i>topology</i>[, <i>object</i>[, <i>filter</i>]]) [<>](https://github.com/topojson/topojson-client/blob/master/src/mesh.js#L4 "Source")
|
||||
|
||||
Returns the GeoJSON MultiLineString geometry object representing the mesh for the specified *object* in the given *topology*. This is useful for rendering strokes in complicated objects efficiently, as edges that are shared by multiple features are only stroked once. If *object* is not specified, a mesh of the entire topology is returned. The returned geometry is a shallow copy of the source *object*: they may share coordinates.
|
||||
|
||||
An optional *filter* function may be specified to prune arcs from the returned mesh using the topology. The filter function is called once for each candidate arc and takes two arguments, *a* and *b*, two geometry objects that share that arc. Each arc is only included in the resulting mesh if the filter function returns true. For typical map topologies the geometries *a* and *b* are adjacent polygons and the candidate arc is their boundary. If an arc is only used by a single geometry then *a* and *b* are identical. This property is useful for separating interior and exterior boundaries; an easy way to produce a mesh of interior boundaries is:
|
||||
|
||||
```js
|
||||
var interiors = topojson.mesh(topology, object, function(a, b) { return a !== b; });
|
||||
```
|
||||
|
||||
See this [county choropleth](https://bl.ocks.org/mbostock/4060606) for example. Note: the *a* and *b* objects are TopoJSON objects (pulled directly from the topology), and not automatically converted to GeoJSON features as by [topojson.feature](#feature).
|
||||
|
||||
<a name="meshArcs" href="#meshArcs">#</a> topojson.<b>meshArcs</b>(<i>topology</i>[, <i>object</i>[, <i>filter</i>]]) [<>](https://github.com/topojson/topojson-client/blob/master/src/mesh.js#L8 "Source")
|
||||
|
||||
Equivalent to [topojson.mesh](#mesh), but returns TopoJSON rather than GeoJSON. The returned geometry is a shallow copy of the source *object*: they may share coordinates.
|
||||
|
||||
<a name="neighbors" href="#neighbors">#</a> topojson.<b>neighbors</b>(<i>objects</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/neighbors.js "Source")
|
||||
|
||||
Returns an array representing the set of neighboring objects for each object in the specified *objects* array. The returned array has the same number of elements as the input array; each element *i* in the returned array is the array of indexes for neighbors of object *i* in the input array. For example, if the specified objects array contains the features *foo* and *bar*, and these features are neighbors, the returned array will be \[\[1\], \[0\]\], indicating that *foo* is a neighbor of *bar* and *vice versa*. Each array of neighbor indexes for each object is guaranteed to be sorted in ascending order.
|
||||
|
||||
For a practical example, see the [world map](https://bl.ocks.org/mbostock/4180634) with topological coloring.
|
||||
|
||||
### Transforms
|
||||
|
||||
<a name="bbox" href="#bbox">#</a> topojson.<b>bbox</b>(<i>topology</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/bbox.js "Source")
|
||||
|
||||
Returns the computed [bounding box](https://github.com/topojson/topojson-specification#3-bounding-boxes) of the specified *topology* [*x*₀, *y*₀, *x*₁, *y*₁] where *x*₀ is the minimum *x*-value, *y*₀ is the minimum *y*-value, *x*₁ is the maximum *x*-value, and *y*₁ is the maximum *y*-value. If the *topology* has no points and no arcs, the returned bounding box is [∞, ∞, -∞, -∞]. (This method ignores the existing *topology*.bbox, if any.)
|
||||
|
||||
<a name="quantize" href="#quantize">#</a> topojson.<b>quantize</b>(<i>topology</i>, <i>transform</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/quantize.js "Source")
|
||||
|
||||
Returns a shallow copy of the specified *topology* with [quantized and delta-encoded](https://github.com/topojson/topojson-specification#213-arcs) arcs according to the specified [*transform* object](https://github.com/topojson/topojson-specification/blob/master/README.md#212-transforms). If the *topology* is already quantized, an error is thrown. See also [topoquantize](#topoquantize).
|
||||
|
||||
If a quantization number *n* is specified instead of a *transform* object, the corresponding transform object is first computed using the bounding box of the topology. In this case, the quantization number *n* must be a positive integer greater than one which determines the maximum number of expressible values per dimension in the resulting quantized coordinates; typically, a power of ten is chosen such as 1e4, 1e5 or 1e6. If the *topology* does not already have a *topology*.bbox, one is computed using [topojson.bbox](#bbox).
|
||||
|
||||
<a name="transform" href="#transform">#</a> topojson.<b>transform</b>(<i>transform</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/transform.js "Source")
|
||||
|
||||
If the specified [*transform* object](https://github.com/topojson/topojson-specification/blob/master/README.md#212-transforms) is non-null, returns a [point *transform* function](#_transform) to remove delta-encoding and apply the transform. If the *transform* is null, returns the identity function.
|
||||
|
||||
<a name="untransform" href="#untransform">#</a> topojson.<b>untransform</b>(<i>transform</i>) [<>](https://github.com/topojson/topojson-client/blob/master/src/untransform.js "Source")
|
||||
|
||||
If the specified [*transform* object](https://github.com/topojson/topojson-specification/blob/master/README.md#212-transforms) is non-null, returns a [point *transform* function](#_transform) to apply quantized delta-encoding and remove the transform. If the *transform* is null, returns the identity function. See also [topojson.quantize](#quantize).
|
||||
|
||||
<a name="_transform" href="#_transform">#</a> <i>transform</i>(<i>point</i>[, <i>index</i>])
|
||||
|
||||
Applies this transform function to the specified *point*, returning a new point with the transformed coordinates. If the specified *index* is truthy, the input *point* is treated as relative to the previous point passed to this transform, as is the case with delta-encoded arcs.
|
||||
|
||||
## Command Line Reference
|
||||
|
||||
### topo2geo
|
||||
|
||||
<a name="topo2geo" href="#topo2geo">#</a> <b>topo2geo</b> [<i>options…</i>] <<i>name</i>=<i>file</i>>… [<>](https://github.com/topojson/topojson-client/blob/master/bin/topo2geo "Source")
|
||||
|
||||
Converts one or more TopoJSON objects from an input topology to one or more GeoJSON features. For example, to convert the “states” TopoJSON GeometryCollection object in us.json to a GeoJSON feature collection in us-states.json:
|
||||
|
||||
```
|
||||
topo2geo states=us-states.json < us.json
|
||||
```
|
||||
|
||||
For convenience, you can omit the object name and specify only the file *name*; the object name will be the basename of the file, with the directory and extension removed. For example, to convert the “states” TopoJSON GeometryCollection object in us.json to a GeoJSON feature collection in states.json:
|
||||
|
||||
```
|
||||
topo2geo states.json < us.json
|
||||
```
|
||||
|
||||
See also [geo2topo](https://github.com/topojson/topojson/blob/master/README.md#geo2topo).
|
||||
|
||||
To list the available object names, use [--list](#topo2geo_list).
|
||||
|
||||
<a name="topo2geo_help" href="#topo2geo_help">#</a> topo2geo <b>-h</b>
|
||||
<br><a href="#topo2geo_help">#</a> topo2geo <b>--help</b>
|
||||
|
||||
Output usage information.
|
||||
|
||||
<a name="topo2geo_version" href="#topo2geo_version">#</a> topo2geo <b>-V</b>
|
||||
<br><a href="#topo2geo_version">#</a> topo2geo <b>--version</b>
|
||||
|
||||
Output the version number.
|
||||
|
||||
<a name="topo2geo_newline_delimited" href="#topo2geo_newline_delimited">#</a> topo2geo <b>-n</b>
|
||||
<br><a href="#topo2geo_newline_delimited">#</a> topo2geo <b>--newline-delimited</b>
|
||||
|
||||
Output [newline-delimited JSON](http://ndjson.org/), with one feature per line.
|
||||
|
||||
<a name="topo2geo_in" href="#topo2geo_in">#</a> topo2geo <b>-i</b> <i>file</i>
|
||||
<br><a href="#topo2geo_in">#</a> topo2geo <b>--in</b> <i>file</i>
|
||||
|
||||
Specify the input TopoJSON file name. Defaults to “-” for stdin.
|
||||
|
||||
<a name="topo2geo_list" href="#topo2geo_list">#</a> topo2geo <b>-l</b>
|
||||
<br><a href="#topo2geo_list">#</a> topo2geo <b>--list</b>
|
||||
|
||||
List the names of the objects in the input topology, and then exit. For example, this:
|
||||
|
||||
```
|
||||
topo2geo -l < us.json
|
||||
```
|
||||
|
||||
Will output this:
|
||||
|
||||
```
|
||||
counties
|
||||
states
|
||||
nation
|
||||
```
|
||||
|
||||
### topomerge
|
||||
|
||||
<a name="topomerge" href="#topomerge">#</a> <b>topomerge</b> [<i>options…</i>] <<i>target</i>=<i>source</i>> [<i>file</i>] [<>](https://github.com/topojson/topojson-client/blob/master/bin/topomerge "Source")
|
||||
|
||||
Merges polygons (or meshes lines) from the specified *source* TopoJSON geometry collection object, assigning to the *target* object.
|
||||
|
||||
See also [topojson.mergeArcs](#mergeArcs) and [topojson.meshArcs](#meshArcs).
|
||||
|
||||
<a name="topomerge_help" href="#topomerge_help">#</a> topomerge <b>-h</b>
|
||||
<br><a href="#topomerge_help">#</a> topomerge <b>--help</b>
|
||||
|
||||
Output usage information.
|
||||
|
||||
<a name="topomerge_version" href="#topomerge_version">#</a> topomerge <b>-V</b>
|
||||
<br><a href="#topomerge_version">#</a> topomerge <b>--version</b>
|
||||
|
||||
Output the version number.
|
||||
|
||||
<a name="topomerge_out" href="#topomerge_out">#</a> topomerge <b>-o</b> <i>file</i>
|
||||
<br><a href="#topomerge_out">#</a> topomerge <b>--out</b> <i>file</i>
|
||||
|
||||
Specify the output TopoJSON file name. Defaults to “-” for stdout.
|
||||
|
||||
<a name="topomerge_key" href="#topomerge_key">#</a> topomerge <b>-k</b> <i>expression</i>
|
||||
<br><a href="#topomerge_key">#</a> topomerge <b>--key</b> <i>expression</i>
|
||||
|
||||
Specify a JavaScript *expression*, given a TopoJSON geometry object *d* and its zero-based index *i* in its parent collection, that determines how geometry objects are grouped before merging; each group is merged separately. For example, given a topology of U.S. *counties*, where the *id* of each county is it’s five-digit FIPS code, the county boundaries can be merged into state boundaries by using the first two digits of the county FIPS code, which represents the state FIPS code:
|
||||
|
||||
```
|
||||
topomerge states=counties -k 'd.id.slice(0, 2)' < us-counties.json > us-states.json
|
||||
```
|
||||
|
||||
If a key is not specified, all input geometry objects will be merged together. For example, this can be used to merge the state boundaries into a single nation boundary:
|
||||
|
||||
```
|
||||
topomerge nation=states < us-states.json > us.json
|
||||
```
|
||||
|
||||
<a name="topomerge_filter" href="#topomerge_filter">#</a> topomerge <b>-f</b> <i>expression</i>
|
||||
<br><a href="#topomerge_filter">#</a> topomerge <b>--filter</b> <i>expression</i>
|
||||
|
||||
Specify a JavaScript *expression* that filters the input geometries before merging or meshing. In conjunction with [--mesh](#topomerge_mesh), the *expression* is given two TopoJSON geometry objects *a* and *b* that represent the adjacent features for a given arc segment; if the *expression* evaluates truthily, the associated arc segment is retained in mesh. Otherwise, the *expression* is given an input TopoJSON geometry object *d* and its zero-based index *i* in its parent collection; if the *expression* evaluates truthily, the geometry object is retained in the merged polygon.
|
||||
|
||||
<a name="topomerge_mesh" href="#topomerge_mesh">#</a> topomerge <b>--mesh</b>
|
||||
|
||||
Use [topojson.meshArcs](#meshArcs) instead of [topojson.mergeArcs](#mergeArcs), generating a geometry collection of lines rather than polygons.
|
||||
|
||||
### topoquantize
|
||||
|
||||
<a name="topoquantize" href="#topoquantize">#</a> <b>topoquantize</b> [<i>options…</i>] <<i>n</i>> [<i>file</i>] [<>](https://github.com/topojson/topojson-client/blob/master/bin/topoquantize "Source")
|
||||
|
||||
Quantizes the coordinates of the input TopoJSON topology and [delta-encodes](https://github.com/topojson/topojson-specification#213-arcs) the topology’s arcs. The quantization parameter *n* must be a positive integer greater than one, and determines the maximum expressible number of unique values per dimension in the resulting quantized coordinates; typically, a power of ten is chosen such as 1e4, 1e5 or 1e6. If the *topology* does not already have a [bbox](#bbox), one is computed and assigned. If the *topology* is already quantized, an error is thrown. See also [topojson.quantize](#quantize).
|
||||
|
||||
<a name="topoquantize_help" href="#topoquantize_help">#</a> topoquantize <b>-h</b>
|
||||
<br><a href="#topoquantize_help">#</a> topoquantize <b>--help</b>
|
||||
|
||||
Output usage information.
|
||||
|
||||
<a name="topoquantize_version" href="#topoquantize_version">#</a> topoquantize <b>-V</b>
|
||||
<br><a href="#topoquantize_version">#</a> topoquantize <b>--version</b>
|
||||
|
||||
Output the version number.
|
||||
|
||||
<a name="topoquantize_out" href="#topoquantize_out">#</a> topoquantize <b>-o</b> <i>file</i>
|
||||
<br><a href="#topoquantize_out">#</a> topoquantize <b>--out</b> <i>file</i>
|
||||
|
||||
Specify the output TopoJSON file name. Defaults to “-” for stdout.
|
||||
106
node_modules/topojson-client/bin/topo2geo
generated
vendored
Executable file
106
node_modules/topojson-client/bin/topo2geo
generated
vendored
Executable file
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require("fs"),
|
||||
path = require("path"),
|
||||
commander = require("commander"),
|
||||
topojson = require("../");
|
||||
|
||||
commander
|
||||
.version(require("../package.json").version)
|
||||
.usage("[options] <name=file>…")
|
||||
.description("Converts TopoJSON objects to GeoJSON features.")
|
||||
.option("-i, --in <file>", "input topology file name; defaults to “-” for stdin", "-")
|
||||
.option("-l, --list", "list the object names on the input topology")
|
||||
.option("-n, --newline-delimited", "output newline-delimited JSON")
|
||||
.parse(process.argv);
|
||||
|
||||
if (!commander.list === commander.args.length < 1) {
|
||||
console.error();
|
||||
console.error(" error: " + (commander.list ? "--list does not take arguments" : "no arguments specified"));
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
read(commander.in).then(write).catch(abort);
|
||||
|
||||
function read(file) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var data = [];
|
||||
readStream(file)
|
||||
.on("data", function(d) { data.push(d); })
|
||||
.on("end", function() { resolve(JSON.parse(Buffer.concat(data))); })
|
||||
.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
function readStream(file) {
|
||||
return file === "-" ? process.stdin : fs.createReadStream(file);
|
||||
}
|
||||
|
||||
function write(topology) {
|
||||
var write, writer = commander.newlineDelimited ? writeNewlineDelimitedFeature : writeFeature, name;
|
||||
if (commander.list) {
|
||||
for (name in topology.objects) {
|
||||
console.log(name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
write = Promise.resolve();
|
||||
commander.args.forEach(function(specifier) {
|
||||
var i = specifier.indexOf("="),
|
||||
file = i >= 0 ? specifier.slice(i + 1) : specifier,
|
||||
name = i >= 0 ? specifier.slice(0, i) : path.basename(specifier, path.extname(specifier));
|
||||
if (!(name in topology.objects)) {
|
||||
console.error();
|
||||
console.error(" error: object “" + name + "” not found");
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
write = write.then(writer(file, topojson.feature(topology, topology.objects[name])));
|
||||
});
|
||||
return write;
|
||||
}
|
||||
|
||||
function writeStream(file) {
|
||||
return (file === "-" ? process.stdout : fs.createWriteStream(file)).on("error", handleEpipe);
|
||||
}
|
||||
|
||||
function writeFeature(file, feature) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
writeStream(file).on("error", reject)[file === "-" ? "write" : "end"](JSON.stringify(feature) + "\n", function(error) {
|
||||
if (error) reject(error);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function writeNewlineDelimitedFeature(file, feature) {
|
||||
return feature == null || feature.type != "FeatureCollection" ? writeFeature(file, feature) : new Promise(function(resolve, reject) {
|
||||
var stream = writeStream(file).on("error", reject), i = -1, n = feature.features.length;
|
||||
|
||||
(function writeNext(error) {
|
||||
if (error) return void reject(error);
|
||||
if (++i >= n) {
|
||||
if (file !== "-") stream.end(writeEnd);
|
||||
else writeEnd();
|
||||
} else {
|
||||
stream.write(JSON.stringify(feature.features[i]) + "\n", writeNext);
|
||||
}
|
||||
})(null);
|
||||
|
||||
function writeEnd(error) {
|
||||
if (error) return void reject(error);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleEpipe(error) {
|
||||
if (error.code === "EPIPE" || error.errno === "EPIPE") {
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
function abort(error) {
|
||||
console.error(error.stack);
|
||||
}
|
||||
216
node_modules/topojson-client/bin/topomerge
generated
vendored
Executable file
216
node_modules/topojson-client/bin/topomerge
generated
vendored
Executable file
@@ -0,0 +1,216 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require("fs"),
|
||||
vm = require("vm"),
|
||||
commander = require("commander"),
|
||||
topojson = require("../");
|
||||
|
||||
commander
|
||||
.version(require("../package.json").version)
|
||||
.usage("[options] <target=source> [file]")
|
||||
.description("Merges the source TopoJSON geometry collection, assigning to the target.")
|
||||
.option("-o, --out <file>", "output topology file name; defaults to “-” for stdout", "-")
|
||||
.option("-k, --key <expression>", "group geometries by key")
|
||||
.option("-f, --filter <expression>", "filter merged geometries or meshed lines")
|
||||
.option("--mesh", "mesh lines instead of merging polygons")
|
||||
.parse(process.argv);
|
||||
|
||||
if (commander.args.length < 1) {
|
||||
console.error();
|
||||
console.error(" error: missing source and target names");
|
||||
console.error();
|
||||
process.exit(1);
|
||||
} else if (commander.args.length > 2) {
|
||||
console.error();
|
||||
console.error(" error: multiple input files");
|
||||
console.error();
|
||||
process.exit(1);
|
||||
} else if (commander.args.length === 1) {
|
||||
commander.args.push("-");
|
||||
}
|
||||
|
||||
var keyFunction = function() {},
|
||||
postfilterFunction = function() { return true; },
|
||||
prefilterFunction = function() { return true; };
|
||||
|
||||
if (commander.key != null) {
|
||||
var keySandbox = {d: undefined, i: -1},
|
||||
keyContext = new vm.createContext(keySandbox),
|
||||
keyScript = new vm.Script("(" + commander.key + ")");
|
||||
keyFunction = function(d, i) {
|
||||
keySandbox.d = d;
|
||||
keySandbox.i = i;
|
||||
return keyScript.runInContext(keyContext);
|
||||
};
|
||||
}
|
||||
|
||||
if (commander.filter != null) {
|
||||
if (commander.mesh) {
|
||||
var filterSandbox = {a: undefined, b: undefined},
|
||||
filterContext = new vm.createContext(filterSandbox),
|
||||
filterScript = new vm.Script("(" + commander.filter + ")");
|
||||
postfilterFunction = function(a, b) {
|
||||
filterSandbox.a = a;
|
||||
filterSandbox.b = b;
|
||||
return filterScript.runInContext(filterContext);
|
||||
};
|
||||
} else {
|
||||
var filterSandbox = {d: undefined, i: -1},
|
||||
filterContext = new vm.createContext(filterSandbox),
|
||||
filterScript = new vm.Script("(" + commander.filter + ")");
|
||||
prefilterFunction = function(d, i) {
|
||||
filterSandbox.d = d;
|
||||
filterSandbox.i = i;
|
||||
return filterScript.runInContext(filterContext);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
read(commander.args[1]).then(merge).then(write(commander.out)).catch(abort);
|
||||
|
||||
function read(file) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var data = [], stream = file === "-" ? process.stdin : fs.createReadStream(file);
|
||||
stream
|
||||
.on("data", function(d) { data.push(d); })
|
||||
.on("end", function() { resolve(JSON.parse(Buffer.concat(data))); })
|
||||
.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
function merge(topology) {
|
||||
var name = commander.args[0], i = name.indexOf("="),
|
||||
sourceName = i >= 0 ? name.slice(i + 1) : name,
|
||||
targetName = i >= 0 ? name.slice(0, i) : name,
|
||||
source = topology.objects[sourceName],
|
||||
target = topology.objects[targetName] = {type: "GeometryCollection", geometries: []},
|
||||
geometries = target.geometries,
|
||||
geometriesByKey = {},
|
||||
k;
|
||||
|
||||
if (!source) {
|
||||
console.error();
|
||||
console.error(" error: source object “" + name + "” not found");
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (source.type !== "GeometryCollection") {
|
||||
console.error();
|
||||
console.error(" error: expected GeometryCollection, not " + source.type);
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
source.geometries.forEach(function(geometry, i) {
|
||||
if (!prefilterFunction(geometry, i)) return;
|
||||
var k = stringify(keyFunction(geometry, i)), v;
|
||||
if (v = geometriesByKey[k]) v.push(geometry);
|
||||
else geometriesByKey[k] = v = [geometry];
|
||||
});
|
||||
|
||||
if (commander.mesh) {
|
||||
for (k in geometriesByKey) {
|
||||
var v = geometriesByKey[k],
|
||||
o = topojson.meshArcs(topology, {type: "GeometryCollection", geometries: v}, postfilterFunction);
|
||||
o.id = k.length > 1 ? k.slice(1) : undefined;
|
||||
o.properties = properties(v);
|
||||
geometries.push(o);
|
||||
}
|
||||
} else {
|
||||
for (k in geometriesByKey) {
|
||||
var v = geometriesByKey[k],
|
||||
o = topojson.mergeArcs(topology, v);
|
||||
o.id = k.length > 1 ? k.slice(1) : undefined;
|
||||
o.properties = properties(v);
|
||||
geometries.push(o);
|
||||
}
|
||||
}
|
||||
|
||||
return topology;
|
||||
}
|
||||
|
||||
function stringify(key) {
|
||||
return key == null ? "$" : "$" + key;
|
||||
}
|
||||
|
||||
function properties(objects) {
|
||||
var properties = undefined, hasProperties;
|
||||
|
||||
objects.forEach(function(object) {
|
||||
var newProperties = object.properties, key;
|
||||
|
||||
// If no properties have yet been merged,
|
||||
// then we need to initialize the merged properties object.
|
||||
if (properties === undefined) {
|
||||
|
||||
// If the first set of properties is null, undefined or empty,
|
||||
// then the result of the merge will be the empty set.
|
||||
// Otherwise, the new properties can copied into the merged object.
|
||||
if (newProperties != null) for (key in newProperties) {
|
||||
properties = {};
|
||||
for (key in newProperties) properties[key] = newProperties[key];
|
||||
return;
|
||||
}
|
||||
|
||||
properties = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// If any of the new properties are null or undefined,
|
||||
// then the result of the merge will be the empty set.
|
||||
if (newProperties == null) properties = null;
|
||||
if (properties === null) return;
|
||||
|
||||
// Now mark as inconsistent any of the properties
|
||||
// that differ from previously-merged values.
|
||||
for (key in newProperties) {
|
||||
if ((key in properties) && !is(properties[key], newProperties[key])) {
|
||||
properties[key] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// And mark as inconsistent any of the properties
|
||||
// that are missing from this new set of merged values.
|
||||
for (key in properties) {
|
||||
if (!(key in newProperties)) {
|
||||
properties[key] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
});
|
||||
|
||||
// Return undefined if there are no properties.
|
||||
for (var key in properties) {
|
||||
if (properties[key] !== undefined) {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function write(file) {
|
||||
var stream = (file === "-" ? process.stdout : fs.createWriteStream(file)).on("error", handleEpipe);
|
||||
return function(topology) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
stream.on("error", reject)[stream === process.stdout ? "write" : "end"](JSON.stringify(topology) + "\n", function(error) {
|
||||
if (error) reject(error);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function handleEpipe(error) {
|
||||
if (error.code === "EPIPE" || error.errno === "EPIPE") {
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
function abort(error) {
|
||||
console.error(error.stack);
|
||||
}
|
||||
|
||||
function is(x, y) {
|
||||
return x === y ? x !== 0 || 1 / x === 1 / y : x !== x && y !== y;
|
||||
}
|
||||
74
node_modules/topojson-client/bin/topoquantize
generated
vendored
Executable file
74
node_modules/topojson-client/bin/topoquantize
generated
vendored
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
var fs = require("fs"),
|
||||
commander = require("commander"),
|
||||
topojson = require("../");
|
||||
|
||||
commander
|
||||
.version(require("../package.json").version)
|
||||
.usage("[options] <n> [file]")
|
||||
.description("Quantizes TopoJSON.")
|
||||
.option("-o, --out <file>", "output topology file name; defaults to “-” for stdout", "-")
|
||||
.parse(process.argv);
|
||||
|
||||
if (commander.args.length < 1) {
|
||||
console.error();
|
||||
console.error(" error: missing quantization parameter n");
|
||||
console.error();
|
||||
process.exit(1);
|
||||
} else if (commander.args.length > 2) {
|
||||
console.error();
|
||||
console.error(" error: multiple input files");
|
||||
console.error();
|
||||
process.exit(1);
|
||||
} else if (commander.args.length === 1) {
|
||||
commander.args.push("-");
|
||||
}
|
||||
|
||||
if (!(Math.floor(commander.args[0]) >= 2)) {
|
||||
console.error();
|
||||
console.error(" error: invalid quantization parameter " + commander.args[0]);
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
read(commander.args[1]).then(quantize).then(write(commander.out)).catch(abort);
|
||||
|
||||
function read(file) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var data = [], stream = file === "-" ? process.stdin : fs.createReadStream(file);
|
||||
stream
|
||||
.on("data", function(d) { data.push(d); })
|
||||
.on("end", function() { resolve(JSON.parse(Buffer.concat(data))); })
|
||||
.on("error", reject);
|
||||
});
|
||||
}
|
||||
|
||||
function quantize(topology) {
|
||||
return topojson.quantize(topology, +commander.args[0]);
|
||||
}
|
||||
|
||||
function write(file) {
|
||||
var stream = (file === "-" ? process.stdout : fs.createWriteStream(file)).on("error", handleEpipe);
|
||||
return function(topology) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
stream.on("error", reject)[stream === process.stdout ? "write" : "end"](JSON.stringify(topology) + "\n", function(error) {
|
||||
if (error) reject(error);
|
||||
else resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function handleEpipe(error) {
|
||||
if (error.code === "EPIPE" || error.errno === "EPIPE") {
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
function abort(error) {
|
||||
console.error();
|
||||
console.error(" error: " + error.message);
|
||||
console.error();
|
||||
process.exit(1);
|
||||
}
|
||||
508
node_modules/topojson-client/dist/topojson-client.js
generated
vendored
Normal file
508
node_modules/topojson-client/dist/topojson-client.js
generated
vendored
Normal file
@@ -0,0 +1,508 @@
|
||||
// https://github.com/topojson/topojson-client v3.1.0 Copyright 2019 Mike Bostock
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
||||
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
||||
(global = global || self, factory(global.topojson = global.topojson || {}));
|
||||
}(this, function (exports) { 'use strict';
|
||||
|
||||
function identity(x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
function transform(transform) {
|
||||
if (transform == null) return identity;
|
||||
var x0,
|
||||
y0,
|
||||
kx = transform.scale[0],
|
||||
ky = transform.scale[1],
|
||||
dx = transform.translate[0],
|
||||
dy = transform.translate[1];
|
||||
return function(input, i) {
|
||||
if (!i) x0 = y0 = 0;
|
||||
var j = 2, n = input.length, output = new Array(n);
|
||||
output[0] = (x0 += input[0]) * kx + dx;
|
||||
output[1] = (y0 += input[1]) * ky + dy;
|
||||
while (j < n) output[j] = input[j], ++j;
|
||||
return output;
|
||||
};
|
||||
}
|
||||
|
||||
function bbox(topology) {
|
||||
var t = transform(topology.transform), key,
|
||||
x0 = Infinity, y0 = x0, x1 = -x0, y1 = -x0;
|
||||
|
||||
function bboxPoint(p) {
|
||||
p = t(p);
|
||||
if (p[0] < x0) x0 = p[0];
|
||||
if (p[0] > x1) x1 = p[0];
|
||||
if (p[1] < y0) y0 = p[1];
|
||||
if (p[1] > y1) y1 = p[1];
|
||||
}
|
||||
|
||||
function bboxGeometry(o) {
|
||||
switch (o.type) {
|
||||
case "GeometryCollection": o.geometries.forEach(bboxGeometry); break;
|
||||
case "Point": bboxPoint(o.coordinates); break;
|
||||
case "MultiPoint": o.coordinates.forEach(bboxPoint); break;
|
||||
}
|
||||
}
|
||||
|
||||
topology.arcs.forEach(function(arc) {
|
||||
var i = -1, n = arc.length, p;
|
||||
while (++i < n) {
|
||||
p = t(arc[i], i);
|
||||
if (p[0] < x0) x0 = p[0];
|
||||
if (p[0] > x1) x1 = p[0];
|
||||
if (p[1] < y0) y0 = p[1];
|
||||
if (p[1] > y1) y1 = p[1];
|
||||
}
|
||||
});
|
||||
|
||||
for (key in topology.objects) {
|
||||
bboxGeometry(topology.objects[key]);
|
||||
}
|
||||
|
||||
return [x0, y0, x1, y1];
|
||||
}
|
||||
|
||||
function reverse(array, n) {
|
||||
var t, j = array.length, i = j - n;
|
||||
while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;
|
||||
}
|
||||
|
||||
function feature(topology, o) {
|
||||
if (typeof o === "string") o = topology.objects[o];
|
||||
return o.type === "GeometryCollection"
|
||||
? {type: "FeatureCollection", features: o.geometries.map(function(o) { return feature$1(topology, o); })}
|
||||
: feature$1(topology, o);
|
||||
}
|
||||
|
||||
function feature$1(topology, o) {
|
||||
var id = o.id,
|
||||
bbox = o.bbox,
|
||||
properties = o.properties == null ? {} : o.properties,
|
||||
geometry = object(topology, o);
|
||||
return id == null && bbox == null ? {type: "Feature", properties: properties, geometry: geometry}
|
||||
: bbox == null ? {type: "Feature", id: id, properties: properties, geometry: geometry}
|
||||
: {type: "Feature", id: id, bbox: bbox, properties: properties, geometry: geometry};
|
||||
}
|
||||
|
||||
function object(topology, o) {
|
||||
var transformPoint = transform(topology.transform),
|
||||
arcs = topology.arcs;
|
||||
|
||||
function arc(i, points) {
|
||||
if (points.length) points.pop();
|
||||
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length; k < n; ++k) {
|
||||
points.push(transformPoint(a[k], k));
|
||||
}
|
||||
if (i < 0) reverse(points, n);
|
||||
}
|
||||
|
||||
function point(p) {
|
||||
return transformPoint(p);
|
||||
}
|
||||
|
||||
function line(arcs) {
|
||||
var points = [];
|
||||
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
|
||||
if (points.length < 2) points.push(points[0]); // This should never happen per the specification.
|
||||
return points;
|
||||
}
|
||||
|
||||
function ring(arcs) {
|
||||
var points = line(arcs);
|
||||
while (points.length < 4) points.push(points[0]); // This may happen if an arc has only two points.
|
||||
return points;
|
||||
}
|
||||
|
||||
function polygon(arcs) {
|
||||
return arcs.map(ring);
|
||||
}
|
||||
|
||||
function geometry(o) {
|
||||
var type = o.type, coordinates;
|
||||
switch (type) {
|
||||
case "GeometryCollection": return {type: type, geometries: o.geometries.map(geometry)};
|
||||
case "Point": coordinates = point(o.coordinates); break;
|
||||
case "MultiPoint": coordinates = o.coordinates.map(point); break;
|
||||
case "LineString": coordinates = line(o.arcs); break;
|
||||
case "MultiLineString": coordinates = o.arcs.map(line); break;
|
||||
case "Polygon": coordinates = polygon(o.arcs); break;
|
||||
case "MultiPolygon": coordinates = o.arcs.map(polygon); break;
|
||||
default: return null;
|
||||
}
|
||||
return {type: type, coordinates: coordinates};
|
||||
}
|
||||
|
||||
return geometry(o);
|
||||
}
|
||||
|
||||
function stitch(topology, arcs) {
|
||||
var stitchedArcs = {},
|
||||
fragmentByStart = {},
|
||||
fragmentByEnd = {},
|
||||
fragments = [],
|
||||
emptyIndex = -1;
|
||||
|
||||
// Stitch empty arcs first, since they may be subsumed by other arcs.
|
||||
arcs.forEach(function(i, j) {
|
||||
var arc = topology.arcs[i < 0 ? ~i : i], t;
|
||||
if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
|
||||
t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
|
||||
}
|
||||
});
|
||||
|
||||
arcs.forEach(function(i) {
|
||||
var e = ends(i),
|
||||
start = e[0],
|
||||
end = e[1],
|
||||
f, g;
|
||||
|
||||
if (f = fragmentByEnd[start]) {
|
||||
delete fragmentByEnd[f.end];
|
||||
f.push(i);
|
||||
f.end = end;
|
||||
if (g = fragmentByStart[end]) {
|
||||
delete fragmentByStart[g.start];
|
||||
var fg = g === f ? f : f.concat(g);
|
||||
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
|
||||
} else {
|
||||
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
|
||||
}
|
||||
} else if (f = fragmentByStart[end]) {
|
||||
delete fragmentByStart[f.start];
|
||||
f.unshift(i);
|
||||
f.start = start;
|
||||
if (g = fragmentByEnd[start]) {
|
||||
delete fragmentByEnd[g.end];
|
||||
var gf = g === f ? f : g.concat(f);
|
||||
fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
|
||||
} else {
|
||||
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
|
||||
}
|
||||
} else {
|
||||
f = [i];
|
||||
fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
|
||||
}
|
||||
});
|
||||
|
||||
function ends(i) {
|
||||
var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
|
||||
if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
|
||||
else p1 = arc[arc.length - 1];
|
||||
return i < 0 ? [p1, p0] : [p0, p1];
|
||||
}
|
||||
|
||||
function flush(fragmentByEnd, fragmentByStart) {
|
||||
for (var k in fragmentByEnd) {
|
||||
var f = fragmentByEnd[k];
|
||||
delete fragmentByStart[f.start];
|
||||
delete f.start;
|
||||
delete f.end;
|
||||
f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
|
||||
fragments.push(f);
|
||||
}
|
||||
}
|
||||
|
||||
flush(fragmentByEnd, fragmentByStart);
|
||||
flush(fragmentByStart, fragmentByEnd);
|
||||
arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
|
||||
|
||||
return fragments;
|
||||
}
|
||||
|
||||
function mesh(topology) {
|
||||
return object(topology, meshArcs.apply(this, arguments));
|
||||
}
|
||||
|
||||
function meshArcs(topology, object, filter) {
|
||||
var arcs, i, n;
|
||||
if (arguments.length > 1) arcs = extractArcs(topology, object, filter);
|
||||
else for (i = 0, arcs = new Array(n = topology.arcs.length); i < n; ++i) arcs[i] = i;
|
||||
return {type: "MultiLineString", arcs: stitch(topology, arcs)};
|
||||
}
|
||||
|
||||
function extractArcs(topology, object, filter) {
|
||||
var arcs = [],
|
||||
geomsByArc = [],
|
||||
geom;
|
||||
|
||||
function extract0(i) {
|
||||
var j = i < 0 ? ~i : i;
|
||||
(geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});
|
||||
}
|
||||
|
||||
function extract1(arcs) {
|
||||
arcs.forEach(extract0);
|
||||
}
|
||||
|
||||
function extract2(arcs) {
|
||||
arcs.forEach(extract1);
|
||||
}
|
||||
|
||||
function extract3(arcs) {
|
||||
arcs.forEach(extract2);
|
||||
}
|
||||
|
||||
function geometry(o) {
|
||||
switch (geom = o, o.type) {
|
||||
case "GeometryCollection": o.geometries.forEach(geometry); break;
|
||||
case "LineString": extract1(o.arcs); break;
|
||||
case "MultiLineString": case "Polygon": extract2(o.arcs); break;
|
||||
case "MultiPolygon": extract3(o.arcs); break;
|
||||
}
|
||||
}
|
||||
|
||||
geometry(object);
|
||||
|
||||
geomsByArc.forEach(filter == null
|
||||
? function(geoms) { arcs.push(geoms[0].i); }
|
||||
: function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });
|
||||
|
||||
return arcs;
|
||||
}
|
||||
|
||||
function planarRingArea(ring) {
|
||||
var i = -1, n = ring.length, a, b = ring[n - 1], area = 0;
|
||||
while (++i < n) a = b, b = ring[i], area += a[0] * b[1] - a[1] * b[0];
|
||||
return Math.abs(area); // Note: doubled area!
|
||||
}
|
||||
|
||||
function merge(topology) {
|
||||
return object(topology, mergeArcs.apply(this, arguments));
|
||||
}
|
||||
|
||||
function mergeArcs(topology, objects) {
|
||||
var polygonsByArc = {},
|
||||
polygons = [],
|
||||
groups = [];
|
||||
|
||||
objects.forEach(geometry);
|
||||
|
||||
function geometry(o) {
|
||||
switch (o.type) {
|
||||
case "GeometryCollection": o.geometries.forEach(geometry); break;
|
||||
case "Polygon": extract(o.arcs); break;
|
||||
case "MultiPolygon": o.arcs.forEach(extract); break;
|
||||
}
|
||||
}
|
||||
|
||||
function extract(polygon) {
|
||||
polygon.forEach(function(ring) {
|
||||
ring.forEach(function(arc) {
|
||||
(polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
|
||||
});
|
||||
});
|
||||
polygons.push(polygon);
|
||||
}
|
||||
|
||||
function area(ring) {
|
||||
return planarRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]);
|
||||
}
|
||||
|
||||
polygons.forEach(function(polygon) {
|
||||
if (!polygon._) {
|
||||
var group = [],
|
||||
neighbors = [polygon];
|
||||
polygon._ = 1;
|
||||
groups.push(group);
|
||||
while (polygon = neighbors.pop()) {
|
||||
group.push(polygon);
|
||||
polygon.forEach(function(ring) {
|
||||
ring.forEach(function(arc) {
|
||||
polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {
|
||||
if (!polygon._) {
|
||||
polygon._ = 1;
|
||||
neighbors.push(polygon);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
polygons.forEach(function(polygon) {
|
||||
delete polygon._;
|
||||
});
|
||||
|
||||
return {
|
||||
type: "MultiPolygon",
|
||||
arcs: groups.map(function(polygons) {
|
||||
var arcs = [], n;
|
||||
|
||||
// Extract the exterior (unique) arcs.
|
||||
polygons.forEach(function(polygon) {
|
||||
polygon.forEach(function(ring) {
|
||||
ring.forEach(function(arc) {
|
||||
if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
|
||||
arcs.push(arc);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Stitch the arcs into one or more rings.
|
||||
arcs = stitch(topology, arcs);
|
||||
|
||||
// If more than one ring is returned,
|
||||
// at most one of these rings can be the exterior;
|
||||
// choose the one with the greatest absolute area.
|
||||
if ((n = arcs.length) > 1) {
|
||||
for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {
|
||||
if ((ki = area(arcs[i])) > k) {
|
||||
t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arcs;
|
||||
}).filter(function(arcs) {
|
||||
return arcs.length > 0;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
function bisect(a, x) {
|
||||
var lo = 0, hi = a.length;
|
||||
while (lo < hi) {
|
||||
var mid = lo + hi >>> 1;
|
||||
if (a[mid] < x) lo = mid + 1;
|
||||
else hi = mid;
|
||||
}
|
||||
return lo;
|
||||
}
|
||||
|
||||
function neighbors(objects) {
|
||||
var indexesByArc = {}, // arc index -> array of object indexes
|
||||
neighbors = objects.map(function() { return []; });
|
||||
|
||||
function line(arcs, i) {
|
||||
arcs.forEach(function(a) {
|
||||
if (a < 0) a = ~a;
|
||||
var o = indexesByArc[a];
|
||||
if (o) o.push(i);
|
||||
else indexesByArc[a] = [i];
|
||||
});
|
||||
}
|
||||
|
||||
function polygon(arcs, i) {
|
||||
arcs.forEach(function(arc) { line(arc, i); });
|
||||
}
|
||||
|
||||
function geometry(o, i) {
|
||||
if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
|
||||
else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
|
||||
}
|
||||
|
||||
var geometryType = {
|
||||
LineString: line,
|
||||
MultiLineString: polygon,
|
||||
Polygon: polygon,
|
||||
MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
|
||||
};
|
||||
|
||||
objects.forEach(geometry);
|
||||
|
||||
for (var i in indexesByArc) {
|
||||
for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
|
||||
for (var k = j + 1; k < m; ++k) {
|
||||
var ij = indexes[j], ik = indexes[k], n;
|
||||
if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
|
||||
if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
function untransform(transform) {
|
||||
if (transform == null) return identity;
|
||||
var x0,
|
||||
y0,
|
||||
kx = transform.scale[0],
|
||||
ky = transform.scale[1],
|
||||
dx = transform.translate[0],
|
||||
dy = transform.translate[1];
|
||||
return function(input, i) {
|
||||
if (!i) x0 = y0 = 0;
|
||||
var j = 2,
|
||||
n = input.length,
|
||||
output = new Array(n),
|
||||
x1 = Math.round((input[0] - dx) / kx),
|
||||
y1 = Math.round((input[1] - dy) / ky);
|
||||
output[0] = x1 - x0, x0 = x1;
|
||||
output[1] = y1 - y0, y0 = y1;
|
||||
while (j < n) output[j] = input[j], ++j;
|
||||
return output;
|
||||
};
|
||||
}
|
||||
|
||||
function quantize(topology, transform) {
|
||||
if (topology.transform) throw new Error("already quantized");
|
||||
|
||||
if (!transform || !transform.scale) {
|
||||
if (!((n = Math.floor(transform)) >= 2)) throw new Error("n must be ≥2");
|
||||
box = topology.bbox || bbox(topology);
|
||||
var x0 = box[0], y0 = box[1], x1 = box[2], y1 = box[3], n;
|
||||
transform = {scale: [x1 - x0 ? (x1 - x0) / (n - 1) : 1, y1 - y0 ? (y1 - y0) / (n - 1) : 1], translate: [x0, y0]};
|
||||
} else {
|
||||
box = topology.bbox;
|
||||
}
|
||||
|
||||
var t = untransform(transform), box, key, inputs = topology.objects, outputs = {};
|
||||
|
||||
function quantizePoint(point) {
|
||||
return t(point);
|
||||
}
|
||||
|
||||
function quantizeGeometry(input) {
|
||||
var output;
|
||||
switch (input.type) {
|
||||
case "GeometryCollection": output = {type: "GeometryCollection", geometries: input.geometries.map(quantizeGeometry)}; break;
|
||||
case "Point": output = {type: "Point", coordinates: quantizePoint(input.coordinates)}; break;
|
||||
case "MultiPoint": output = {type: "MultiPoint", coordinates: input.coordinates.map(quantizePoint)}; break;
|
||||
default: return input;
|
||||
}
|
||||
if (input.id != null) output.id = input.id;
|
||||
if (input.bbox != null) output.bbox = input.bbox;
|
||||
if (input.properties != null) output.properties = input.properties;
|
||||
return output;
|
||||
}
|
||||
|
||||
function quantizeArc(input) {
|
||||
var i = 0, j = 1, n = input.length, p, output = new Array(n); // pessimistic
|
||||
output[0] = t(input[0], 0);
|
||||
while (++i < n) if ((p = t(input[i], i))[0] || p[1]) output[j++] = p; // non-coincident points
|
||||
if (j === 1) output[j++] = [0, 0]; // an arc must have at least two points
|
||||
output.length = j;
|
||||
return output;
|
||||
}
|
||||
|
||||
for (key in inputs) outputs[key] = quantizeGeometry(inputs[key]);
|
||||
|
||||
return {
|
||||
type: "Topology",
|
||||
bbox: box,
|
||||
transform: transform,
|
||||
objects: outputs,
|
||||
arcs: topology.arcs.map(quantizeArc)
|
||||
};
|
||||
}
|
||||
|
||||
exports.bbox = bbox;
|
||||
exports.feature = feature;
|
||||
exports.merge = merge;
|
||||
exports.mergeArcs = mergeArcs;
|
||||
exports.mesh = mesh;
|
||||
exports.meshArcs = meshArcs;
|
||||
exports.neighbors = neighbors;
|
||||
exports.quantize = quantize;
|
||||
exports.transform = transform;
|
||||
exports.untransform = untransform;
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
}));
|
||||
2
node_modules/topojson-client/dist/topojson-client.min.js
generated
vendored
Normal file
2
node_modules/topojson-client/dist/topojson-client.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
77
node_modules/topojson-client/package.json
generated
vendored
Normal file
77
node_modules/topojson-client/package.json
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"_from": "topojson-client@^3.1.0",
|
||||
"_id": "topojson-client@3.1.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==",
|
||||
"_location": "/topojson-client",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "topojson-client@^3.1.0",
|
||||
"name": "topojson-client",
|
||||
"escapedName": "topojson-client",
|
||||
"rawSpec": "^3.1.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^3.1.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/vega-loader"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz",
|
||||
"_shasum": "22e8b1ed08a2b922feeb4af6f53b6ef09a467b99",
|
||||
"_spec": "topojson-client@^3.1.0",
|
||||
"_where": "/home/prabhatdev/Documents/opensource/gitHubStats/waka-readme-stats/node_modules/vega-loader",
|
||||
"author": {
|
||||
"name": "Mike Bostock",
|
||||
"url": "https://bost.ocks.org/mike"
|
||||
},
|
||||
"bin": {
|
||||
"topo2geo": "bin/topo2geo",
|
||||
"topomerge": "bin/topomerge",
|
||||
"topoquantize": "bin/topoquantize"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/topojson/topojson-client/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"commander": "2"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Manipulate TopoJSON and convert it to GeoJSON.",
|
||||
"devDependencies": {
|
||||
"eslint": "6",
|
||||
"rollup": "1",
|
||||
"rollup-plugin-terser": "5",
|
||||
"tape": "4"
|
||||
},
|
||||
"files": [
|
||||
"bin/topo*",
|
||||
"dist/**/*.js",
|
||||
"src/**/*.js"
|
||||
],
|
||||
"homepage": "https://github.com/topojson/topojson-client",
|
||||
"jsdelivr": "dist/topojson-client.min.js",
|
||||
"keywords": [
|
||||
"topojson",
|
||||
"topology",
|
||||
"geojson"
|
||||
],
|
||||
"license": "ISC",
|
||||
"main": "dist/topojson-client.js",
|
||||
"module": "src/index.js",
|
||||
"name": "topojson-client",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/topojson/topojson-client.git"
|
||||
},
|
||||
"scripts": {
|
||||
"postpublish": "git push && git push --tags && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js",
|
||||
"prepublishOnly": "rm -rf dist && yarn test",
|
||||
"pretest": "rollup -c",
|
||||
"test": "tape 'test/**/*-test.js' && eslint src test"
|
||||
},
|
||||
"unpkg": "dist/topojson-client.min.js",
|
||||
"version": "3.1.0"
|
||||
}
|
||||
39
node_modules/topojson-client/src/bbox.js
generated
vendored
Normal file
39
node_modules/topojson-client/src/bbox.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import transform from "./transform.js";
|
||||
|
||||
export default function(topology) {
|
||||
var t = transform(topology.transform), key,
|
||||
x0 = Infinity, y0 = x0, x1 = -x0, y1 = -x0;
|
||||
|
||||
function bboxPoint(p) {
|
||||
p = t(p);
|
||||
if (p[0] < x0) x0 = p[0];
|
||||
if (p[0] > x1) x1 = p[0];
|
||||
if (p[1] < y0) y0 = p[1];
|
||||
if (p[1] > y1) y1 = p[1];
|
||||
}
|
||||
|
||||
function bboxGeometry(o) {
|
||||
switch (o.type) {
|
||||
case "GeometryCollection": o.geometries.forEach(bboxGeometry); break;
|
||||
case "Point": bboxPoint(o.coordinates); break;
|
||||
case "MultiPoint": o.coordinates.forEach(bboxPoint); break;
|
||||
}
|
||||
}
|
||||
|
||||
topology.arcs.forEach(function(arc) {
|
||||
var i = -1, n = arc.length, p;
|
||||
while (++i < n) {
|
||||
p = t(arc[i], i);
|
||||
if (p[0] < x0) x0 = p[0];
|
||||
if (p[0] > x1) x1 = p[0];
|
||||
if (p[1] < y0) y0 = p[1];
|
||||
if (p[1] > y1) y1 = p[1];
|
||||
}
|
||||
});
|
||||
|
||||
for (key in topology.objects) {
|
||||
bboxGeometry(topology.objects[key]);
|
||||
}
|
||||
|
||||
return [x0, y0, x1, y1];
|
||||
}
|
||||
9
node_modules/topojson-client/src/bisect.js
generated
vendored
Normal file
9
node_modules/topojson-client/src/bisect.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export default function(a, x) {
|
||||
var lo = 0, hi = a.length;
|
||||
while (lo < hi) {
|
||||
var mid = lo + hi >>> 1;
|
||||
if (a[mid] < x) lo = mid + 1;
|
||||
else hi = mid;
|
||||
}
|
||||
return lo;
|
||||
}
|
||||
70
node_modules/topojson-client/src/feature.js
generated
vendored
Normal file
70
node_modules/topojson-client/src/feature.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import reverse from "./reverse.js";
|
||||
import transform from "./transform.js";
|
||||
|
||||
export default function(topology, o) {
|
||||
if (typeof o === "string") o = topology.objects[o];
|
||||
return o.type === "GeometryCollection"
|
||||
? {type: "FeatureCollection", features: o.geometries.map(function(o) { return feature(topology, o); })}
|
||||
: feature(topology, o);
|
||||
}
|
||||
|
||||
function feature(topology, o) {
|
||||
var id = o.id,
|
||||
bbox = o.bbox,
|
||||
properties = o.properties == null ? {} : o.properties,
|
||||
geometry = object(topology, o);
|
||||
return id == null && bbox == null ? {type: "Feature", properties: properties, geometry: geometry}
|
||||
: bbox == null ? {type: "Feature", id: id, properties: properties, geometry: geometry}
|
||||
: {type: "Feature", id: id, bbox: bbox, properties: properties, geometry: geometry};
|
||||
}
|
||||
|
||||
export function object(topology, o) {
|
||||
var transformPoint = transform(topology.transform),
|
||||
arcs = topology.arcs;
|
||||
|
||||
function arc(i, points) {
|
||||
if (points.length) points.pop();
|
||||
for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length; k < n; ++k) {
|
||||
points.push(transformPoint(a[k], k));
|
||||
}
|
||||
if (i < 0) reverse(points, n);
|
||||
}
|
||||
|
||||
function point(p) {
|
||||
return transformPoint(p);
|
||||
}
|
||||
|
||||
function line(arcs) {
|
||||
var points = [];
|
||||
for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);
|
||||
if (points.length < 2) points.push(points[0]); // This should never happen per the specification.
|
||||
return points;
|
||||
}
|
||||
|
||||
function ring(arcs) {
|
||||
var points = line(arcs);
|
||||
while (points.length < 4) points.push(points[0]); // This may happen if an arc has only two points.
|
||||
return points;
|
||||
}
|
||||
|
||||
function polygon(arcs) {
|
||||
return arcs.map(ring);
|
||||
}
|
||||
|
||||
function geometry(o) {
|
||||
var type = o.type, coordinates;
|
||||
switch (type) {
|
||||
case "GeometryCollection": return {type: type, geometries: o.geometries.map(geometry)};
|
||||
case "Point": coordinates = point(o.coordinates); break;
|
||||
case "MultiPoint": coordinates = o.coordinates.map(point); break;
|
||||
case "LineString": coordinates = line(o.arcs); break;
|
||||
case "MultiLineString": coordinates = o.arcs.map(line); break;
|
||||
case "Polygon": coordinates = polygon(o.arcs); break;
|
||||
case "MultiPolygon": coordinates = o.arcs.map(polygon); break;
|
||||
default: return null;
|
||||
}
|
||||
return {type: type, coordinates: coordinates};
|
||||
}
|
||||
|
||||
return geometry(o);
|
||||
}
|
||||
3
node_modules/topojson-client/src/identity.js
generated
vendored
Normal file
3
node_modules/topojson-client/src/identity.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function(x) {
|
||||
return x;
|
||||
}
|
||||
8
node_modules/topojson-client/src/index.js
generated
vendored
Normal file
8
node_modules/topojson-client/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
export {default as bbox} from "./bbox.js";
|
||||
export {default as feature} from "./feature.js";
|
||||
export {default as mesh, meshArcs} from "./mesh.js";
|
||||
export {default as merge, mergeArcs} from "./merge.js";
|
||||
export {default as neighbors} from "./neighbors.js";
|
||||
export {default as quantize} from "./quantize.js";
|
||||
export {default as transform} from "./transform.js";
|
||||
export {default as untransform} from "./untransform.js";
|
||||
103
node_modules/topojson-client/src/merge.js
generated
vendored
Normal file
103
node_modules/topojson-client/src/merge.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
import {object} from "./feature.js";
|
||||
import stitch from "./stitch.js";
|
||||
|
||||
function planarRingArea(ring) {
|
||||
var i = -1, n = ring.length, a, b = ring[n - 1], area = 0;
|
||||
while (++i < n) a = b, b = ring[i], area += a[0] * b[1] - a[1] * b[0];
|
||||
return Math.abs(area); // Note: doubled area!
|
||||
}
|
||||
|
||||
export default function(topology) {
|
||||
return object(topology, mergeArcs.apply(this, arguments));
|
||||
}
|
||||
|
||||
export function mergeArcs(topology, objects) {
|
||||
var polygonsByArc = {},
|
||||
polygons = [],
|
||||
groups = [];
|
||||
|
||||
objects.forEach(geometry);
|
||||
|
||||
function geometry(o) {
|
||||
switch (o.type) {
|
||||
case "GeometryCollection": o.geometries.forEach(geometry); break;
|
||||
case "Polygon": extract(o.arcs); break;
|
||||
case "MultiPolygon": o.arcs.forEach(extract); break;
|
||||
}
|
||||
}
|
||||
|
||||
function extract(polygon) {
|
||||
polygon.forEach(function(ring) {
|
||||
ring.forEach(function(arc) {
|
||||
(polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);
|
||||
});
|
||||
});
|
||||
polygons.push(polygon);
|
||||
}
|
||||
|
||||
function area(ring) {
|
||||
return planarRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]);
|
||||
}
|
||||
|
||||
polygons.forEach(function(polygon) {
|
||||
if (!polygon._) {
|
||||
var group = [],
|
||||
neighbors = [polygon];
|
||||
polygon._ = 1;
|
||||
groups.push(group);
|
||||
while (polygon = neighbors.pop()) {
|
||||
group.push(polygon);
|
||||
polygon.forEach(function(ring) {
|
||||
ring.forEach(function(arc) {
|
||||
polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {
|
||||
if (!polygon._) {
|
||||
polygon._ = 1;
|
||||
neighbors.push(polygon);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
polygons.forEach(function(polygon) {
|
||||
delete polygon._;
|
||||
});
|
||||
|
||||
return {
|
||||
type: "MultiPolygon",
|
||||
arcs: groups.map(function(polygons) {
|
||||
var arcs = [], n;
|
||||
|
||||
// Extract the exterior (unique) arcs.
|
||||
polygons.forEach(function(polygon) {
|
||||
polygon.forEach(function(ring) {
|
||||
ring.forEach(function(arc) {
|
||||
if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {
|
||||
arcs.push(arc);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Stitch the arcs into one or more rings.
|
||||
arcs = stitch(topology, arcs);
|
||||
|
||||
// If more than one ring is returned,
|
||||
// at most one of these rings can be the exterior;
|
||||
// choose the one with the greatest absolute area.
|
||||
if ((n = arcs.length) > 1) {
|
||||
for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {
|
||||
if ((ki = area(arcs[i])) > k) {
|
||||
t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return arcs;
|
||||
}).filter(function(arcs) {
|
||||
return arcs.length > 0;
|
||||
})
|
||||
};
|
||||
}
|
||||
53
node_modules/topojson-client/src/mesh.js
generated
vendored
Normal file
53
node_modules/topojson-client/src/mesh.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import {object} from "./feature.js";
|
||||
import stitch from "./stitch.js";
|
||||
|
||||
export default function(topology) {
|
||||
return object(topology, meshArcs.apply(this, arguments));
|
||||
}
|
||||
|
||||
export function meshArcs(topology, object, filter) {
|
||||
var arcs, i, n;
|
||||
if (arguments.length > 1) arcs = extractArcs(topology, object, filter);
|
||||
else for (i = 0, arcs = new Array(n = topology.arcs.length); i < n; ++i) arcs[i] = i;
|
||||
return {type: "MultiLineString", arcs: stitch(topology, arcs)};
|
||||
}
|
||||
|
||||
function extractArcs(topology, object, filter) {
|
||||
var arcs = [],
|
||||
geomsByArc = [],
|
||||
geom;
|
||||
|
||||
function extract0(i) {
|
||||
var j = i < 0 ? ~i : i;
|
||||
(geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});
|
||||
}
|
||||
|
||||
function extract1(arcs) {
|
||||
arcs.forEach(extract0);
|
||||
}
|
||||
|
||||
function extract2(arcs) {
|
||||
arcs.forEach(extract1);
|
||||
}
|
||||
|
||||
function extract3(arcs) {
|
||||
arcs.forEach(extract2);
|
||||
}
|
||||
|
||||
function geometry(o) {
|
||||
switch (geom = o, o.type) {
|
||||
case "GeometryCollection": o.geometries.forEach(geometry); break;
|
||||
case "LineString": extract1(o.arcs); break;
|
||||
case "MultiLineString": case "Polygon": extract2(o.arcs); break;
|
||||
case "MultiPolygon": extract3(o.arcs); break;
|
||||
}
|
||||
}
|
||||
|
||||
geometry(object);
|
||||
|
||||
geomsByArc.forEach(filter == null
|
||||
? function(geoms) { arcs.push(geoms[0].i); }
|
||||
: function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });
|
||||
|
||||
return arcs;
|
||||
}
|
||||
45
node_modules/topojson-client/src/neighbors.js
generated
vendored
Normal file
45
node_modules/topojson-client/src/neighbors.js
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import bisect from "./bisect.js";
|
||||
|
||||
export default function(objects) {
|
||||
var indexesByArc = {}, // arc index -> array of object indexes
|
||||
neighbors = objects.map(function() { return []; });
|
||||
|
||||
function line(arcs, i) {
|
||||
arcs.forEach(function(a) {
|
||||
if (a < 0) a = ~a;
|
||||
var o = indexesByArc[a];
|
||||
if (o) o.push(i);
|
||||
else indexesByArc[a] = [i];
|
||||
});
|
||||
}
|
||||
|
||||
function polygon(arcs, i) {
|
||||
arcs.forEach(function(arc) { line(arc, i); });
|
||||
}
|
||||
|
||||
function geometry(o, i) {
|
||||
if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); });
|
||||
else if (o.type in geometryType) geometryType[o.type](o.arcs, i);
|
||||
}
|
||||
|
||||
var geometryType = {
|
||||
LineString: line,
|
||||
MultiLineString: polygon,
|
||||
Polygon: polygon,
|
||||
MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
|
||||
};
|
||||
|
||||
objects.forEach(geometry);
|
||||
|
||||
for (var i in indexesByArc) {
|
||||
for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {
|
||||
for (var k = j + 1; k < m; ++k) {
|
||||
var ij = indexes[j], ik = indexes[k], n;
|
||||
if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);
|
||||
if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return neighbors;
|
||||
}
|
||||
54
node_modules/topojson-client/src/quantize.js
generated
vendored
Normal file
54
node_modules/topojson-client/src/quantize.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
import bbox from "./bbox.js";
|
||||
import untransform from "./untransform.js";
|
||||
|
||||
export default function(topology, transform) {
|
||||
if (topology.transform) throw new Error("already quantized");
|
||||
|
||||
if (!transform || !transform.scale) {
|
||||
if (!((n = Math.floor(transform)) >= 2)) throw new Error("n must be ≥2");
|
||||
box = topology.bbox || bbox(topology);
|
||||
var x0 = box[0], y0 = box[1], x1 = box[2], y1 = box[3], n;
|
||||
transform = {scale: [x1 - x0 ? (x1 - x0) / (n - 1) : 1, y1 - y0 ? (y1 - y0) / (n - 1) : 1], translate: [x0, y0]};
|
||||
} else {
|
||||
box = topology.bbox;
|
||||
}
|
||||
|
||||
var t = untransform(transform), box, key, inputs = topology.objects, outputs = {};
|
||||
|
||||
function quantizePoint(point) {
|
||||
return t(point);
|
||||
}
|
||||
|
||||
function quantizeGeometry(input) {
|
||||
var output;
|
||||
switch (input.type) {
|
||||
case "GeometryCollection": output = {type: "GeometryCollection", geometries: input.geometries.map(quantizeGeometry)}; break;
|
||||
case "Point": output = {type: "Point", coordinates: quantizePoint(input.coordinates)}; break;
|
||||
case "MultiPoint": output = {type: "MultiPoint", coordinates: input.coordinates.map(quantizePoint)}; break;
|
||||
default: return input;
|
||||
}
|
||||
if (input.id != null) output.id = input.id;
|
||||
if (input.bbox != null) output.bbox = input.bbox;
|
||||
if (input.properties != null) output.properties = input.properties;
|
||||
return output;
|
||||
}
|
||||
|
||||
function quantizeArc(input) {
|
||||
var i = 0, j = 1, n = input.length, p, output = new Array(n); // pessimistic
|
||||
output[0] = t(input[0], 0);
|
||||
while (++i < n) if ((p = t(input[i], i))[0] || p[1]) output[j++] = p; // non-coincident points
|
||||
if (j === 1) output[j++] = [0, 0]; // an arc must have at least two points
|
||||
output.length = j;
|
||||
return output;
|
||||
}
|
||||
|
||||
for (key in inputs) outputs[key] = quantizeGeometry(inputs[key]);
|
||||
|
||||
return {
|
||||
type: "Topology",
|
||||
bbox: box,
|
||||
transform: transform,
|
||||
objects: outputs,
|
||||
arcs: topology.arcs.map(quantizeArc)
|
||||
};
|
||||
}
|
||||
4
node_modules/topojson-client/src/reverse.js
generated
vendored
Normal file
4
node_modules/topojson-client/src/reverse.js
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export default function(array, n) {
|
||||
var t, j = array.length, i = j - n;
|
||||
while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;
|
||||
}
|
||||
73
node_modules/topojson-client/src/stitch.js
generated
vendored
Normal file
73
node_modules/topojson-client/src/stitch.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
export default function(topology, arcs) {
|
||||
var stitchedArcs = {},
|
||||
fragmentByStart = {},
|
||||
fragmentByEnd = {},
|
||||
fragments = [],
|
||||
emptyIndex = -1;
|
||||
|
||||
// Stitch empty arcs first, since they may be subsumed by other arcs.
|
||||
arcs.forEach(function(i, j) {
|
||||
var arc = topology.arcs[i < 0 ? ~i : i], t;
|
||||
if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {
|
||||
t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;
|
||||
}
|
||||
});
|
||||
|
||||
arcs.forEach(function(i) {
|
||||
var e = ends(i),
|
||||
start = e[0],
|
||||
end = e[1],
|
||||
f, g;
|
||||
|
||||
if (f = fragmentByEnd[start]) {
|
||||
delete fragmentByEnd[f.end];
|
||||
f.push(i);
|
||||
f.end = end;
|
||||
if (g = fragmentByStart[end]) {
|
||||
delete fragmentByStart[g.start];
|
||||
var fg = g === f ? f : f.concat(g);
|
||||
fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;
|
||||
} else {
|
||||
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
|
||||
}
|
||||
} else if (f = fragmentByStart[end]) {
|
||||
delete fragmentByStart[f.start];
|
||||
f.unshift(i);
|
||||
f.start = start;
|
||||
if (g = fragmentByEnd[start]) {
|
||||
delete fragmentByEnd[g.end];
|
||||
var gf = g === f ? f : g.concat(f);
|
||||
fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;
|
||||
} else {
|
||||
fragmentByStart[f.start] = fragmentByEnd[f.end] = f;
|
||||
}
|
||||
} else {
|
||||
f = [i];
|
||||
fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;
|
||||
}
|
||||
});
|
||||
|
||||
function ends(i) {
|
||||
var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;
|
||||
if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });
|
||||
else p1 = arc[arc.length - 1];
|
||||
return i < 0 ? [p1, p0] : [p0, p1];
|
||||
}
|
||||
|
||||
function flush(fragmentByEnd, fragmentByStart) {
|
||||
for (var k in fragmentByEnd) {
|
||||
var f = fragmentByEnd[k];
|
||||
delete fragmentByStart[f.start];
|
||||
delete f.start;
|
||||
delete f.end;
|
||||
f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });
|
||||
fragments.push(f);
|
||||
}
|
||||
}
|
||||
|
||||
flush(fragmentByEnd, fragmentByStart);
|
||||
flush(fragmentByStart, fragmentByEnd);
|
||||
arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });
|
||||
|
||||
return fragments;
|
||||
}
|
||||
19
node_modules/topojson-client/src/transform.js
generated
vendored
Normal file
19
node_modules/topojson-client/src/transform.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import identity from "./identity.js";
|
||||
|
||||
export default function(transform) {
|
||||
if (transform == null) return identity;
|
||||
var x0,
|
||||
y0,
|
||||
kx = transform.scale[0],
|
||||
ky = transform.scale[1],
|
||||
dx = transform.translate[0],
|
||||
dy = transform.translate[1];
|
||||
return function(input, i) {
|
||||
if (!i) x0 = y0 = 0;
|
||||
var j = 2, n = input.length, output = new Array(n);
|
||||
output[0] = (x0 += input[0]) * kx + dx;
|
||||
output[1] = (y0 += input[1]) * ky + dy;
|
||||
while (j < n) output[j] = input[j], ++j;
|
||||
return output;
|
||||
};
|
||||
}
|
||||
23
node_modules/topojson-client/src/untransform.js
generated
vendored
Normal file
23
node_modules/topojson-client/src/untransform.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import identity from "./identity.js";
|
||||
|
||||
export default function(transform) {
|
||||
if (transform == null) return identity;
|
||||
var x0,
|
||||
y0,
|
||||
kx = transform.scale[0],
|
||||
ky = transform.scale[1],
|
||||
dx = transform.translate[0],
|
||||
dy = transform.translate[1];
|
||||
return function(input, i) {
|
||||
if (!i) x0 = y0 = 0;
|
||||
var j = 2,
|
||||
n = input.length,
|
||||
output = new Array(n),
|
||||
x1 = Math.round((input[0] - dx) / kx),
|
||||
y1 = Math.round((input[1] - dy) / ky);
|
||||
output[0] = x1 - x0, x0 = x1;
|
||||
output[1] = y1 - y0, y0 = y1;
|
||||
while (j < n) output[j] = input[j], ++j;
|
||||
return output;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user