You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改Google-Maps-iOS-Utils框架实现热力图按平均权重着色

How to Modify GMUHeatmapTileLayer to Use Average Weight Instead of Summed Intensity

Got it, let's tackle this! The GMUHeatmapTileLayer's default behavior sums weighted intensity values across the convolution, but to switch to an average weight per pixel, we need to track two things for each pixel: the total weighted intensity and the sum of the kernel weights that contributed to it. Then we can divide the total intensity by the kernel sum to get the average.

Here's how to modify the -tileForX:y:zoom: method's convolution logic:

Step 1: Track both total intensity and kernel contribution counts

We'll add two new arrays to keep track of the sum of kernel weights (so we can compute the average later) — one for the horizontal convolution phase, one for the vertical phase.

Modified Horizontal Convolution Code

- (UIImage *)tileForX:(NSUInteger)x y:(NSUInteger)y zoom:(NSUInteger)zoom {
// ... (existing code before convolution)
// Convolve data.
int lowerLimit = (int)data->_radius;
int upperLimit = paddedTileSize - (int)data->_radius - 1;
// Convolve horizontally first.
float *intermediate = calloc(paddedTileSize * paddedTileSize, sizeof(float));
// NEW: Array to track sum of kernel weights for horizontal phase
float *intermediateCount = calloc(paddedTileSize * paddedTileSize, sizeof(float));

for (int y = 0; y < paddedTileSize; y++) {
for (int x = 0; x < paddedTileSize; x++) {
float value = intensity[y * paddedTileSize + x];
if (value != 0) {
int start = MAX(lowerLimit, x - (int)data->_radius);
int end = MIN(upperLimit, x + (int)data->_radius);
for (int x2 = start; x2 <= end; x2++) {
float kernelValue = [data->_kernel[x2 - x + data->_radius] floatValue];
float scaledKernel = value * kernelValue;
// Accumulate weighted intensity
intermediate[y * paddedTileSize + x2] += scaledKernel;
// Accumulate kernel weight count
intermediateCount[y * paddedTileSize + x2] += kernelValue;
}
}
}
}

// NEW: Compute horizontal average by dividing total intensity by kernel sum
for (int y = 0; y < paddedTileSize; y++) {
    for (int x = 0; x < paddedTileSize; x++) {
        int index = y * paddedTileSize + x;
        if (intermediateCount[index] > 0.0001) { // Avoid division by zero
            intermediate[index] /= intermediateCount[index];
        }
    }
}

free(intensity);
free(intermediateCount); // Clean up the count array
// ...

Modified Vertical Convolution Code

// Convole vertically to get final intensity.
float *finalIntensity = calloc(kGMUTileSize * kGMUTileSize, sizeof(float));
// NEW: Array to track sum of kernel weights for vertical phase
float *finalCount = calloc(kGMUTileSize * kGMUTileSize, sizeof(float));

for (int x = lowerLimit; x <= upperLimit; x++) {
for (int y = 0; y < paddedTileSize; y++) {
float value = intermediate[y * paddedTileSize + x];
if (value != 0) {
int start = MAX(lowerLimit, y - (int)data->_radius);
int end = MIN(upperLimit, y + (int)data->_radius);
for (int y2 = start; y2 <= end; y2++) {
float kernelValue = [data->_kernel[y2 - y + data->_radius] floatValue];
float scaledKernel = value * kernelValue;
int finalIndex = (y2 - lowerLimit) * kGMUTileSize + x - lowerLimit;
// Accumulate weighted intensity
finalIntensity[finalIndex] += scaledKernel;
// Accumulate kernel weight count
finalCount[finalIndex] += kernelValue;
}
}
}
}

// NEW: Compute final average by dividing total intensity by kernel sum
for (int i = 0; i < kGMUTileSize * kGMUTileSize; i++) {
    if (finalCount[i] > 0.0001) { // Avoid division by zero
        finalIntensity[i] /= finalCount[i];
    }
}

free(intermediate);
free(finalCount); // Clean up the count array
// ... (existing code to render the tile from finalIntensity)
}

Key Changes Explained

  1. Tracking Kernel Counts: We added intermediateCount and finalCount arrays to sum up the Gaussian kernel values applied to each pixel. This tells us how much each point's weight contributed to the pixel (via the kernel's falloff).
  2. Calculating Averages: After each convolution phase, we divide the total weighted intensity by the sum of kernel weights for that pixel. This gives us the weighted average of the nearby points' intensities, using the Gaussian kernel as the weighting factor.
  3. Division by Zero Safety: We check if the count is greater than a small threshold (0.0001) instead of just 0 to avoid floating-point precision issues.

This modification will make the heatmap color each pixel based on the average weight of points in its surrounding area (smoothed by the Gaussian kernel), instead of the total summed intensity.

内容的提问来源于stack exchange,提问作者IHaveAQuestion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:44:15