topojson / topojson-client

Manipulate TopoJSON, such as to merge shapes, and convert it back to GeoJSON.
ISC License
213 stars 63 forks source link

Extract borders? #17

Closed Fil closed 7 years ago

Fil commented 7 years ago

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.

mbostock commented 7 years ago

So, like, topojson.meshes? Normally I implement this by doing multiple passes and filtering accordingly, but yes, it might be more efficient to have a method to construct multiple disjoint meshes in one pass.

Fil commented 7 years ago

Yes. The API could be simpler than what I coded here, as there is no need to use filter and tag functions at the same time. (If you don't want some part of the mesh, just tag it "0" or something, and filter it out from the partition.)

So, topojson.meshes(topology, objects, tag(a,b)) would return the list of tagged meshes.

To avoid code duplication, topojson.mesh(topology, objects, filter(a,b)) could use topojson.meshes(topology, objects, !!filter(a,b)) and return only the mesh tagged true — it would make a (small?) memory overhead though, so I'm not sure you'd like that.

[Updated my block accordingly]

Fil commented 7 years ago

Another option is to use the tag to filter as well as to partition, the rule being that if the tag is false-ish, the arcs are ignored. Then we would have (almost) no overhead for the simpler .mesh(), and no code duplication. I'm pushing this solution as #18 — it's just a proposition.