[GIS] How to restrict Mapshaper’s `-dissolve` to merge only certain specified features on a layer

mapshaper

I'm try to merge a few specified features on a topojson map using Mapshaper. For this example, I'm trying to merge Somalia, Somaliland and Puntland to match a dataset that doesn't separate them.

Mapshaper has command features, -dissolve and -dissolve2, that seem to do what I want. However, they seem to apply to every feature in the selected layer, and I can't see any obvious way in the Mapshaper docs to select only certain features within a layer to apply to.

The options name and target apply to files and layers respectively, not features. Likewise all the usage examples I can find don't select specific features to merge.

There's a feature to limit it by field:

Name of a data field to dissolve on.

… but I can't find any way to pipe in a list of field values. I can specify the name field, but can't find a way to specify that the name field should be "Somalia" or "Somaliland".

If possible, I'd prefer not to move the features onto a temporary dummy layer then move them back again.

Ideally I'd use something similar to how -each and -filter allow to match by an expression but that doesn't seem to exist for -dissolve. For example, this, which works perfectly for -filter, doesn't work:

 -dissolve '(NAME == "Somaliland" || NAME == "Puntland" || NAME == "Somalia")'

…because that parameter must be a field name and can't be an expression:

Data table is missing field: (NAME == "Somaliland" || NAME == "Puntland" || NAME == "Somalia")

Best Answer

This works for -dissolve, but doesn't merge the selected features with -dissolve2.


Essentially, you can edit or create a field using -each so that every feature has a different value except the ones you want merged, then, dissolve on that field. This is complicated a little by two things:

  • Your dummy field needs to be defined for all features on this layer, else -dissolve will fail:

    Data table is missing field: someFieldName

  • Dissolve erases all feature data fields except the one you dissolve on, including FID, unless you expressly tell it not to.


So, there are a few steps:

  1. Choose a field where each feature has a different unique value, where you can overwrite it for the features that are to be resolved. For example, in my data, let's say every feature has a unique NAME and I am merging NAME=Somaliland and NAME=Puntland into NAME=Somalia

    • If for any reason such a field doesn't exist already, you can create a dummy one and use the inbuilt MapShaper ID to give it a unique value. So for example if there's no suitable field and NAME is undefined:

      -each 'NAME=this.id'
      
  2. Run an -each command to give the features you want to target the same value:

    -each 'NAME="Somalia"' where='(NAME == "Puntland" || NAME == "Somaliland")'
    
    • Or if no such field existed before and you created a dummy field, in the Mapshaper UI you can find the ID numbers by clicking on the i button then clicking on the features of interest to look up their ID numbers and target them that way:

      -each 'NAME="Somalia"' where='(NAME == "5" || NAME == "8" || NAME == "9")'
      
  3. Run a -dissolve specifying this field and specifying which field data to keep.

    -dissolve NAME copy-fields='some,field,names,here'

    The field used to dissolve on is copied automatically. There doesn't seem to be any "copy all option". Also note that:

    copy-fields= Fields to copy when dissolving (comma-sep. list). Copies values from the first feature in each group of dissolved features.

    ...so check the values are what you want and if they aren't, you might need to do some more -eachs to make sure the right field values are the ones the final merged feature gets.

Related Question