Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Centroids from Property Name (new module proposal) #841

Closed
3 tasks
DenisCarriere opened this issue Jul 14, 2017 · 8 comments
Closed
3 tasks

Create Centroids from Property Name (new module proposal) #841

DenisCarriere opened this issue Jul 14, 2017 · 8 comments

Comments

@DenisCarriere
Copy link
Member

DenisCarriere commented Jul 14, 2017

New Module proposal

Module based on @stebogit's need to create centroids from clusters (FeatureCollection of Points).

Abstract implementation of creating centroids which all features are entirely filtered by GeoJSON Properties (input not specific to only Points Collection, all GeoJSON types should be supported).

/**
 * Basic implementation of creating centroids based on a single Property
 * Can be expanded with very complex property combination
 *
 * @param {FeatureCollection|Feature[]} geojson GeoJSON
 * @param {string} property Name of property of GeoJSON Properties to bin each feature - This property will be translated to each centroid's properties
 * @param {*} properties Properties to translate down to each centroid (2nd priority)
 * @returns {FeatureCollection<Point>} centroids
 * @example
 * var centroids = centroidFromProperty(points, 'cluster');
 */
function centroidFromProperty(geojson, property, properties) {

No idea what this would be called (centroids-from-properties?)... got to sleep on that one.

Could also integrate all 3 centroid based operations:

  • center
  • centroid
  • center-of-mass

@stebogit Thoughts?

Considerations

  • Translate property values to centroids
  • Handle undefined properties (points should be excluded if they don't contain the property)
  • Handle Array of Features as valid input (Simply need to wrap FeatureCollection)

Source Code example (Draft)

function centroidFromProperty(geojson, property, properties) {
    if (Array.isArray(geojson)) geojson = featureCollection(geojson);

    const centroids = [];
    const bins = new Map();
    featureEach(geojson, feature => {
        const prop = feature.properties[property];
        if (prop === undefined) return;
        if (bins.has(prop)) bins.get(prop).push(feature);
        else bins.set(prop, [feature]);
    });
    bins.forEach(features => {
        // Retrieve property of first feature (only the defined property tags, nothing else)
        const props = JSON.parse(JSON.stringify(properties));
        props[property] = features[0].properties[property];
        const centroid = centerOfMass(featureCollection(features), props);
        centroids.push(centroid);
    });
    return featureCollection(centroids);
}
@stebogit
Copy link
Collaborator

@DenisCarriere I don't necessarily see the need of a new module. Sorry maybe I was not clear here.

My thought is that when you apply any @turf/clusters- modules you end up having basically just the same FeatureCollection of points, properly labeled.
However I guess (I'm not actually going to be using any of these modules) you used the clustering module to be able to do stuff with/on one or more clusters (not always defining their centroids); so with the current implementation (of both clustering modules) after clustering you need to iterate through all your points again (clusters- already did) to group/parse them so that you can do stuff on a single cluster for example (like simply adding a marker-icon).
If the output had an additional field with just the ids for each label it would make a little easier/faster/flexible any iteration.
That's all, and it might just be irrelevant.

@DenisCarriere
Copy link
Member Author

Abstracting these types of features/modules makes it so we don't need to "bundle" them into every module, even though it's doing 1 extra iteration (forEach), it's so fast that it won't really impact any of the processing. It actually slows things down if a user doesn't need the centroids calculated, so it's better to leave that out.

We should do the same for clusters-kmeans, that way the output is a pure GeoJSON FeatureCollection and there's no confusion or over complicated @returns explanations. A FeatureCollection with cluster property tag is already plenty enough.

@DenisCarriere
Copy link
Member Author

I don't necessarily see the need of a new module.

👾 🚀 Future you will need this module

@DenisCarriere DenisCarriere self-assigned this Jul 14, 2017
@stebogit
Copy link
Collaborator

@DenisCarriere why don't we use this module to apply a function, passed as parameter, to the set of points identified by the property, like a featureEach or coordEach.
We might call it clusterEach.

@DenisCarriere
Copy link
Member Author

🥇 That's an even better idea, that way we can apply "whatever" method we throw at it (concaveman or centroid).

👍 I like clusterEach/clusterReduce which will be used in @turf/meta.

@DenisCarriere
Copy link
Member Author

Going to close this issue and re-create one using clusterEach/clusterReduce as the main topic.

@stebogit
Copy link
Collaborator

@DenisCarriere I'd add also a getCluster to the mix 😃

@DenisCarriere
Copy link
Member Author

Maybe we should place all these types of methods as part of parent @turf/cluster module:

  • @turf/cluster-kmean
  • @turf/cluster-dbscan
  • @turf/cluster
    • getCluster
    • clusterEach
    • clusterReduce

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants