function getKeplerLayers(
  idsInSegmentgroups,
  geoFeatures,
  isVisible,
  colorByFeature
) {
  // iterate each feature
  const layersInfoNested = geoFeatures.map((geoFeatureDef, geoFeatureId) => {
    // no need to create 2 layers if this is an agregated layer
    if (!geoFeatureDef.pair) {
      return {
        geoFeatureDef,
        geoFeatureId,
      };
    }
    // iterate each segment groups since no per-layer filtering is supported T3638323 https://github.com/keplergl/kepler.gl/issues/403
    return idsInSegmentgroups.map((dataIds, segmentGroupId) => {
      return {
        geoFeatureDef,
        geoFeatureId,
        numDataPoints: dataIds.length,
        segmentGroupId,
      };
    });
  });
  // flatten
  const layersInfo = [].concat.apply([], layersInfoNested);

  return layersInfo.map(info => {
    const {geoFeatureDef, geoFeatureId, numDataPoints, segmentGroupId} = info;

    const layerSuffix = segmentGroupId
      ? `group_${segmentGroupId}`
      : 'aggregated';
    const layerId = `${geoFeatureDef.name}_${layerSuffix}`;
    const type = getLayerType(geoFeatureDef);
    // if this is hexagonId layer, point to the aggregated dataset
    const dataId =
      type === 'hexagonId'
        ? `${KEPLER_DATASET_NAME}_hex_${geoFeatureDef.name}`
        : `${KEPLER_DATASET_NAME}_${segmentGroupId}`;
    const columns = getLayerColumns(geoFeatureDef, type);
    const visualChannels = getLayerVisualChannels(type, colorByFeature);
    const visConfig = getLayerVisConfig(type, numDataPoints, segmentGroupId);

    return {
      id: layerId,
      type,
      config: {
        dataId,
        label: layerId,
        columns,
        isVisible: isVisible[geoFeatureId],
        visConfig,
      },
      visualChannels,
    };
  });
}
@param {Array<Array<Number>>} idsInSegmentgroups array of 2 arrays of row ids, representing data points in 2 segment groups
@param {Array<Object>} geoFeatures geo feature definitions, contains {name, pair}. geoFeatures.pair is an array of 2 geo feature definitions representing lat, lng columns of that feature
@param {Array<Boolean>} isVisible whether each geo feature is visible
@param {Object} colorByFeature field definition by which to color visual layers, contains {name, type, tableFieldIndex}
@returns layer field of kepler config