mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Weight outlieriness by categoricality
This commit is contained in:
+15
-9
@@ -908,6 +908,20 @@ std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double categorical_hash(std::string const &val) {
|
||||||
|
unsigned hash = 0;
|
||||||
|
for (size_t i = 0; i < val.size(); i++) {
|
||||||
|
// https://en.wikipedia.org/wiki/Hash_function#Fibonacci_hashing
|
||||||
|
hash = hash * 2654435769 + val[i];
|
||||||
|
}
|
||||||
|
// extra multiply so even single-byte values are distributed
|
||||||
|
// around the circle rather than clumped together on one side.
|
||||||
|
hash = hash * 2654435769;
|
||||||
|
double angle = ((double) hash) / UINT_MAX * 2 * M_PI;
|
||||||
|
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
void add_to_file_keys(std::map<std::string, type_and_string_stats> &file_keys, std::string const &attrib, type_and_string const &val) {
|
void add_to_file_keys(std::map<std::string, type_and_string_stats> &file_keys, std::string const &attrib, type_and_string const &val) {
|
||||||
if (val.type == mvt_null) {
|
if (val.type == mvt_null) {
|
||||||
return;
|
return;
|
||||||
@@ -944,15 +958,7 @@ void add_to_file_keys(std::map<std::string, type_and_string_stats> &file_keys, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned hash = 0;
|
double angle = categorical_hash(val.string);
|
||||||
for (size_t i = 0; i < val.string.size(); i++) {
|
|
||||||
// https://en.wikipedia.org/wiki/Hash_function#Fibonacci_hashing
|
|
||||||
hash = hash * 2654435769 + val.string[i];
|
|
||||||
}
|
|
||||||
// extra multiply so even single-byte values are distributed
|
|
||||||
// around the circle rather than clumped together on one side.
|
|
||||||
hash = hash * 2654435769;
|
|
||||||
double angle = ((double) hash) / UINT_MAX * 2 * M_PI;
|
|
||||||
double x = cos(angle);
|
double x = cos(angle);
|
||||||
double y = sin(angle);
|
double y = sin(angle);
|
||||||
|
|
||||||
|
|||||||
@@ -93,5 +93,6 @@ std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::
|
|||||||
std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::string, layermap_entry> > const &maps, bool trunc);
|
std::map<std::string, layermap_entry> merge_layermaps(std::vector<std::map<std::string, layermap_entry> > const &maps, bool trunc);
|
||||||
|
|
||||||
void add_to_file_keys(std::map<std::string, type_and_string_stats> &file_keys, std::string const &layername, type_and_string const &val);
|
void add_to_file_keys(std::map<std::string, type_and_string_stats> &file_keys, std::string const &layername, type_and_string const &val);
|
||||||
|
double categorical_hash(std::string const &value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -241,7 +241,6 @@ static int metacmp(const std::vector<long long> &keys1, const std::vector<long l
|
|||||||
}
|
}
|
||||||
|
|
||||||
double get_interestingness(const serial_feature *sf, const std::map<std::string, layermap_entry> *merged_layermaps, std::string const &layername) {
|
double get_interestingness(const serial_feature *sf, const std::map<std::string, layermap_entry> *merged_layermaps, std::string const &layername) {
|
||||||
double interestingness = 0;
|
|
||||||
auto layer = merged_layermaps->find(layername);
|
auto layer = merged_layermaps->find(layername);
|
||||||
if (layer == merged_layermaps->end()) {
|
if (layer == merged_layermaps->end()) {
|
||||||
fprintf(stderr, "Can't find layer %s\n", layername.c_str());
|
fprintf(stderr, "Can't find layer %s\n", layername.c_str());
|
||||||
@@ -250,24 +249,35 @@ double get_interestingness(const serial_feature *sf, const std::map<std::string,
|
|||||||
|
|
||||||
for (size_t i = 0; i < sf->keys.size(); i++) {
|
for (size_t i = 0; i < sf->keys.size(); i++) {
|
||||||
mvt_value key = retrieve_string(sf->keys[i], sf->stringpool, NULL);
|
mvt_value key = retrieve_string(sf->keys[i], sf->stringpool, NULL);
|
||||||
mvt_value value = retrieve_string(sf->values[i], sf->stringpool, NULL);
|
|
||||||
|
|
||||||
#if 0
|
auto const tass = layer->second.file_keys.find(key.string_value);
|
||||||
// this needs to find the layer before it can find the attribute
|
if (tass != layer->second.file_keys.end()) {
|
||||||
auto lm = merged_layermaps->find(key.string_value);
|
// mvt_value value = retrieve_string(sf->values[i], sf->stringpool, NULL);
|
||||||
if (lm != merged_layermaps->end()) {
|
|
||||||
// how categorical is it?
|
|
||||||
|
|
||||||
double xd = lm->second.xsum / lm->second.count;
|
double xd = tass->second.xsum / tass->second.count;
|
||||||
double yd = lm->second.ysum / lm->second.count;
|
double yd = tass->second.ysum / tass->second.count;
|
||||||
double d = sqrt(xd * xd + yd * yd);
|
|
||||||
|
|
||||||
|
// This will be 0 for something that is not categorical at all,
|
||||||
|
// 1 for something that is so categorical that there is only one value,
|
||||||
|
// and above 0.3 or so for something that is more reasonably categorical.
|
||||||
|
double categoricality = sqrt(xd * xd + yd * yd);
|
||||||
|
|
||||||
|
if (categoricality != 1) {
|
||||||
|
double angle = categorical_hash(sf->stringpool + sf->values[i] + 1);
|
||||||
|
xd -= cos(angle);
|
||||||
|
yd -= sin(angle);
|
||||||
|
|
||||||
|
// This will be 0 for something that matches the single categorical value,
|
||||||
|
// almost 2 for something that is an extreme categorical outlier,
|
||||||
|
// or somewhere in between for more reasonably categorical values.
|
||||||
|
double interestingness = sqrt(xd * xd + yd * yd);
|
||||||
|
|
||||||
|
printf("%f: %s %s\n", categoricality * interestingness, key.string_value.c_str(), sf->stringpool + sf->values[i] + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return interestingness;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static mvt_value find_attribute_value(const serial_feature *sf, std::string key, const std::map<std::string, layermap_entry> *merged_layermaps, std::string const &layername) {
|
static mvt_value find_attribute_value(const serial_feature *sf, std::string key, const std::map<std::string, layermap_entry> *merged_layermaps, std::string const &layername) {
|
||||||
|
|||||||
Reference in New Issue
Block a user