Giter VIP home page Giter VIP logo

topojson-client's Introduction

TopoJSON

TopoJSON is an extension of GeoJSON that encodes topology. Rather than representing geometries discretely, geometries in TopoJSON files are stitched together from shared line segments called arcs. This technique is similar to Matt Bloch’s MapShaper and the Arc/Info Export format, .e00.

TopoJSON eliminates redundancy, allowing related geometries to be stored efficiently in the same file. For example, the shared boundary between California and Nevada is represented only once, rather than being duplicated for both states. A single TopoJSON file can contain multiple feature collections without duplication, such as states and counties. Or, a TopoJSON file can efficiently represent both polygons (for fill) and boundaries (for stroke) as two feature collections that share the same arc mesh. See How To Infer Topology for a visual explanation of how TopoJSON works. See Command-Line Cartography for an introduction to TopoJSON and related tools. See TopoJSON Format Specification for the format specification.

To further reduce file size, TopoJSON can use quantized delta-encoding for integer coordinates. This is similar to rounding coordinate values (e.g., LilJSON), but with greater efficiency and control over loss of information. And like GeoJSON, TopoJSON files are easily modified in a text editor and amenable to gzip compression.

As a result, TopoJSON is substantially more compact than GeoJSON, frequently offering a reduction of 80% or more even without simplification. Yet encoding topology also has numerous useful applications for maps and visualization above! It allows topology-preserving shape simplification, which ensures that adjacent features remain connected after simplification; this applies even across feature collections, such as simultaneous consistent simplification of state and county boundaries. Topology can also be used for Dorling or hexagonal cartograms, as well as other techniques that need shared boundary information such as automatic map coloring.

Installing

If you use NPM, npm install topojson. Otherwise, download the latest release. You can also load directly from d3js.org as a standalone library. AMD, CommonJS, and vanilla environments are supported. In vanilla, a topojson global is exported:

<script src="https://unpkg.com/topojson@3"></script>
<script>

var topology = topojson.topology({foo: geojson});

</script>

Try topojson in your browser.

API Reference

topojson-client's People

Contributors

denisname avatar mbostock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

topojson-client's Issues

topojson.feature(topology, name)

It’d be convenient to allow the feature to be specified as a name, e.g.

topojson.feature(topology, "foo")

would be equivalent to

topojson.feature(topology, topology.objects.foo)

Adopt ESM?

Hi, are you planning to adopt ESM?

Thanks!

Quantization shouldn’t use [0,0] for the last point of empty arcs.

If an arc collapses down to a single point during quantization, we add a [0,0] at the end to ensure that each arc has at least two points, per the specification. The problem with this is that it implicitly drops any additional dimensions (beyond x and y) of the coincident points.

So, it’d be better to add the last point p instead of making a new point [0,0], so that any additional dimensions in the last point p are preserved. This assumes that the input arc has at least two points, but that should be a reasonable assumption given the specification.

topojson.mesh filter doesn’t support geometry with multiple neighbors

If there are more than two geometries in a collection that share the same arcs, the mesh filter function will ignore some neighboring geometries.

For instance, given the following topology, the filter function will never be passed geometry with id 2.

var topology = {
  "type": "Topology",
  "objects": {
    "collection": {
      "type": "GeometryCollection",
      "geometries": [
        {"id": 1, "type": "LineString", "arcs": [0,1]},
        {"id": 2, "type": "LineString", "arcs": [0,1]},
        {"id": 3, "type": "LineString", "arcs": [0,1]}
      ]
    }
  },
  "arcs": [
    [[1, 0], [2, 0]],
    [[0, 0], [1, 0]]
  ]
};

topojson.mesh(topology, topology.objects.collection, function (geometry, neighbor) {
  return geometry.id === 2 || neighbor.id === 2;
});

For a more practical use case, in the screenshot below the bold line is created with a mesh filter intend to outline Uganda. However, since Uganda shares borders with both Kenya and Kenya’s states, the filter fails and the border is partially missing.

screen shot 2017-03-17 at 8 45 33 am

The issue appears to be in the extractArcs function (https://github.com/topojson/topojson-client/blob/master/src/mesh.js#L50) where only the first and last neighbors are sent to the filter function.

Here are some possible solutions that I could think of:

  • pass all geometries as a third argument to the filter function.
function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g, geoms.map(function(geom) { return geom.g; })) arcs.push(geoms[0].i); });
  • only pass all geometries to the filter function.
function(geoms) { if (filter(geoms.map(function(geom) { return geom.g; }))) arcs.push(geoms[0].i); });
  • pass each geometry as an individual argument to the filter function
function(geoms) { if (filter.apply(this, geoms.map(function(geom) { return geom.g; }))) arcs.push(geoms[0].i); });
  • allow the way the filter function is applied to be changed as an optional argument to the mesh function
topojson.mesh(topology, object, filter, [apply = defaultApply])

function defaultApply(geometries, filterFn) {
  return geometries.reduce(function (accum, geom, i, geoms) {
    if (accum === false) return false;
    return filterFn(geoms[0], geom);
  }, true);
}

function (geoms) { 
  var apply = apply || defaultApply;
  if(apply(geoms.map(function(geom) { return geom.g; }), filter) arcs.push(geoms[0].i); 
});

suggestion: format topojson neighbors the same way as a force links object

Because I am working with both right now, I am wondering why links objects (from d3.force) and neighbors objects (from d3.geo) are structured differently, whereas they are substantially equivalent.

Since neighbors are, to my knowledge, not used directly in any subsequent functions, I would suggest to structure them as links objects.

Topojson.feature() Returning Undefined

I am trying to render districts outlines on a map using updated topojson file which I created from geojson file.

I successfully made the original file create map using d3. Bu then, I added more features created using "geojson.io". I did so by exporting features in geojson format, appending them to original districts geojson file and then finally converting the updated geojson file to topojson using geo2topo. cli

The new topojson file seems to run perfectly on "geojson.io", "mapShaper". But in my app, on passing the topology and topojson object to topojson-client's feature method, it returns undefined.

I've checked the initial topojson file with new one. All the keys/ values are there, and that because latter works on above mentioned sites. I've been forced to believe there is some bug in the method which is returning undefined.

Add default export

Right now, the only way to add use the the topojson-client is to import it like this:

import * as topojson from "topojson-client";

What if we export it in a way that we can use it like:

import topojson from "topojson-client";

topomerge can't deduplicate geometries

I expected topomerge to be able to deduplicate geometries but it didn't work:

topomerge -k 'd.id' < foo.json

Geometries come out like this:

{"type":"MultiPolygon","arcs":[[]],"id":"1"}
// etc.

As a workaround I used ndjson-reduce 'p[d.id] = d, p' '{}' | ndjson-split 'Object.values(d)' on the GeoJSON features first.

toposcale

It’d be nice to have a binary for taking projected, planar TopoJSON as input and then modifying the transform (or computing the transformed coordinates, if there is no transform) so that the TopoJSON fits in the desired bounding box. It should also support --invert for flipping the y-dimension, as Proj4 and other projection systems typically use the other y direction than Canvas and SVG.

https://github.com/topojson/topojson/blob/v1.6.27/lib/topojson/scale.js

Extract borders?

Currently topojson.mesh() returns one big mesh, and no simple way to extract borders and tag them by neighbors (for example).

Could it be interesting to have an extension of topojson.mesh() that allows a tag(a,b) function to partition the resulting mesh?

Here's a block that demonstrates the idea (with code adapted from src/mesh.js):
http://blockbuilder.org/Fil/9ff0ca1825369075394d0e77e149052c

Notice how the two lines between USA and Canada belong to the same MultiLineString (they have the same tag). The coastline is tagged 0 and also is a unique MultiLineString.

Make stitchedArcs a Set.

I have a minor nudge.

var stitchedArcs = {}

Looking at the life-cycle of the object stitchedArcs

It has the characteristics of a set ( i.e. a [key,value] pairs where the value is only ever set to '1' )

I would like to make this semantically more precise.

By semantically I mean I want to, lock this down, to give assurances that the value is never accidentally incremented or set to a a value like as 'socks'.

I am about to submit a three line PR

topojson.feature of a FeatureCollection of MultiPolygons returns a "Feature" object with null as geometry property

I have the topojson file in attachment:
topojson_issue.json.txt

which I made with the "pytopojson" library. I'm pretty confident it looks ok, library doesn't complain but I guess there isn't an online validator. Geojson-wise it's a feature collection of 20 multipolygons. I use the following snippet in javascript:

d3.json("https://75.119.131.164/data/hourly_homezones.json", function(error, topology) {
    console.log(topojson.feature(topology, topology.objects.my_geojson.geometries));
};

which returns:

image

I don't think this is an expected response. I expect a featurecollection of multipolygons.

Any foolish mistake I'm making ? Or is this a bug ?

topojson.{feature,mesh} without copying points.

One of the biggest performance costs in topojson.feature (and topojson.mesh) is calling array.slice on every point. There are times when this is needed, but in many cases it would be perfectly reasonable to modify the coordinates in-place when applying the transform, and to avoid the copy when creating a feature or mesh. We should design an appropriate API to enable this faster path.

Moved from topojson/topojson#215.

Add absolute and relative.

topojson.absolute([transform])

If the specified transform is non-null, returns a function that removes the delta-encoding from the specified arc and applies the specified transform. The specified arc coordinates are modified in-place, and the arc is returned. If the specified transform is null, returns the identity function.

topojson.relative(transform)

If the specified transform is non-null, returns a function that applies the delta-encoding to the specified arc and removes the specified transform. The specified arc coordinates are modified in-place, and the arc is returned. If the specified transform is null, returns the identity function.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.