prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Improve cluster accuracy
  Cluster aggregates markers in `in_cluster` is using box instead of a circle parameter calculation which I think may cause duplications and inaccuracy
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `static/pymapcluster.py`
  Content:
  ```
  1 ##
  2 import globalmaptiles as globaltiles
  3 from math import cos, sin, atan2, sqrt
  4 import time
  5 ##
  6  
  7 def center_geolocation(geolocations):
  8     """
  9     Provide a relatively accurate center lat, lon returned as a list pair, given
  10     a list of list pairs.
  11     ex: in: geolocations = ((lat1,lon1), (lat2,lon2),)
  12         out: (center_lat, center_lon)
  13     """
  14     x = 0
  15     y = 0
  16     z = 0
  17  
  18     for lat, lon in geolocations:
  19         lat = float(lat)
  20         lon = float(lon)
  21         x += cos(lat) * cos(lon)
  22         y += cos(lat) * sin(lon)
  23         z += sin(lat)
  24  
  25     x = float(x / len(geolocations))
  26     y = float(y / len(geolocations))
  27     z = float(z / len(geolocations))
  28  
  29     return (atan2(y, x), atan2(z, sqrt(x * x + y * y)))
  30 
  31 def latlng_to_zoompixels(mercator, lat, lng, zoom):
  32     mx, my = mercator.LatLonToMeters(lat, lng)
  33     pix = mercator.MetersToPixels(mx, my, zoom)
  34     return pix
  35 
  36 def in_cluster(center, radius, point):
  37     return (point[0] >= center[0] - radius) and (point[0] <= center[0] + radius) \
  38        and (point[1] >= center[1] - radius) and (point[1] <= center[1] + radius)
  39 
  40 def cluster_markers(mercator, latlngs, zoom, gridsize=50):
  41     """
  42     Args:
  43         mercator: instance of GlobalMercator()
  44         latlngs: list of (lat,lng) tuple
  45         zoom: current zoom level
  46         gridsize: cluster radius (in pixels in current zoom level)
  47     Returns:
  48         centers: list of indices in latlngs of points used as centers
  49         clusters: list of same length as latlngs giving assigning each point to
  50                   a cluster
  51     """
  52     start_time = time.time()
  53     centers = []
  54     clusters = []
  55     sizes = []
  56     latlngs = map(lambda latlng: latlng.serialize(), latlngs)
  57     for i, latlng in enumerate(latlngs):
  58         lat = latlng['latitude']
  59         lng = latlng['longitude']
  60         point_pix = latlng_to_zoompixels(mercator, lat, lng, zoom)
  61         assigned = False
  62         for cidx, c in enumerate(centers):
  63             center = latlngs[c]
  64             center = latlng_to_zoompixels(mercator, center['latitude'], center['longitude'], zoom)
  65             if in_cluster(center, gridsize, point_pix):
  66                 # Assign point to cluster
  67                 clusters.append(cidx)
  68                 sizes[cidx] += 1
  69                 assigned = True
  70                 break
  71         if not assigned:
  72             # Create new cluster for point
  73             #TODO center_geolocation the center!
  74             centers.append(i)
  75             sizes.append(1)
  76             clusters.append(len(centers) - 1)
  77 
  78     print('time for cluster_markers: ' + str(time.time() - start_time))
  79     return centers, clusters, sizes
  80 
  81 def create_clusters_centers(markers, zoom, radius):
  82     mercator = globaltiles.GlobalMercator()
  83     centers, clusters, sizes = cluster_markers(mercator, markers, zoom, radius)
  84     centers_markers = [markers[i] for i in centers]
  85     return centers_markers, clusters, sizes
  86 
  87 def get_cluster_json(clust_marker, clust_size):
  88     return {
  89         'longitude': clust_marker.longitude,
  90         'latitude': clust_marker.latitude,
  91         'size': clust_size
  92     }
  93 
  94 def get_cluster_size(index, clusters):
  95     from collections import Counter
  96     #TODO: don't call Counter for every cluster in the array
  97     return Counter(clusters)[index]
  98 
  99 def generate_clusters_json(markers, zoom, radius=50):
  100     centers, clusters, sizes = create_clusters_centers(markers, zoom, radius)
  101     json_clusts=[]
  102 
  103     for i, point in enumerate(centers):
  104         json_clusts.append(get_cluster_json(point, sizes[i]))
  105 
  106     return {
  107         'clusters': json_clusts
  108     }
  109 
  110 ##
  111 if __name__ == '__main__':
  112     ##
  113     mercator = globaltiles.GlobalMercator()
  114     latlngs = [(28.43, 8), (28.43, 8), (28.44, 8), (35, 8)]
  115     centers, clusters = cluster_markers(mercator, latlngs, 21)
  116     ##
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/static/pymapcluster.py b/static/pymapcluster.py
  --- a/static/pymapcluster.py
  +++ b/static/pymapcluster.py
  @@ -34,8 +34,7 @@
       return pix
   
   def in_cluster(center, radius, point):
  -    return (point[0] >= center[0] - radius) and (point[0] <= center[0] + radius) \
  -       and (point[1] >= center[1] - radius) and (point[1] <= center[1] + radius)
  +    return sqrt((point[0] - center[0])**2 + (point[1] - center[1])**2) <= radius
   
   def cluster_markers(mercator, latlngs, zoom, gridsize=50):
       """
  
verification_info: {"golden_diff": "diff --git a/static/pymapcluster.py b/static/pymapcluster.py\n--- a/static/pymapcluster.py\n+++ b/static/pymapcluster.py\n@@ -34,8 +34,7 @@\n     return pix\n \n def in_cluster(center, radius, point):\n-    return (point[0] >= center[0] - radius) and (point[0] <= center[0] + radius) \\\n-       and (point[1] >= center[1] - radius) and (point[1] <= center[1] + radius)\n+    return sqrt((point[0] - center[0])**2 + (point[1] - center[1])**2) <= radius\n \n def cluster_markers(mercator, latlngs, zoom, gridsize=50):\n     \"\"\"\n", "issue": "Improve cluster accuracy\nCluster aggregates markers in `in_cluster` is using box instead of a circle parameter calculation which I think may cause duplications and inaccuracy\n\n", "before_files": [{"content": "##\nimport globalmaptiles as globaltiles\nfrom math import cos, sin, atan2, sqrt\nimport time\n##\n \ndef center_geolocation(geolocations):\n    \"\"\"\n    Provide a relatively accurate center lat, lon returned as a list pair, given\n    a list of list pairs.\n    ex: in: geolocations = ((lat1,lon1), (lat2,lon2),)\n        out: (center_lat, center_lon)\n    \"\"\"\n    x = 0\n    y = 0\n    z = 0\n \n    for lat, lon in geolocations:\n        lat = float(lat)\n        lon = float(lon)\n        x += cos(lat) * cos(lon)\n        y += cos(lat) * sin(lon)\n        z += sin(lat)\n \n    x = float(x / len(geolocations))\n    y = float(y / len(geolocations))\n    z = float(z / len(geolocations))\n \n    return (atan2(y, x), atan2(z, sqrt(x * x + y * y)))\n\ndef latlng_to_zoompixels(mercator, lat, lng, zoom):\n    mx, my = mercator.LatLonToMeters(lat, lng)\n    pix = mercator.MetersToPixels(mx, my, zoom)\n    return pix\n\ndef in_cluster(center, radius, point):\n    return (point[0] >= center[0] - radius) and (point[0] <= center[0] + radius) \\\n       and (point[1] >= center[1] - radius) and (point[1] <= center[1] + radius)\n\ndef cluster_markers(mercator, latlngs, zoom, gridsize=50):\n    \"\"\"\n    Args:\n        mercator: instance of GlobalMercator()\n        latlngs: list of (lat,lng) tuple\n        zoom: current zoom level\n        gridsize: cluster radius (in pixels in current zoom level)\n    Returns:\n        centers: list of indices in latlngs of points used as centers\n        clusters: list of same length as latlngs giving assigning each point to\n                  a cluster\n    \"\"\"\n    start_time = time.time()\n    centers = []\n    clusters = []\n    sizes = []\n    latlngs = map(lambda latlng: latlng.serialize(), latlngs)\n    for i, latlng in enumerate(latlngs):\n        lat = latlng['latitude']\n        lng = latlng['longitude']\n        point_pix = latlng_to_zoompixels(mercator, lat, lng, zoom)\n        assigned = False\n        for cidx, c in enumerate(centers):\n            center = latlngs[c]\n            center = latlng_to_zoompixels(mercator, center['latitude'], center['longitude'], zoom)\n            if in_cluster(center, gridsize, point_pix):\n                # Assign point to cluster\n                clusters.append(cidx)\n                sizes[cidx] += 1\n                assigned = True\n                break\n        if not assigned:\n            # Create new cluster for point\n            #TODO center_geolocation the center!\n            centers.append(i)\n            sizes.append(1)\n            clusters.append(len(centers) - 1)\n\n    print('time for cluster_markers: ' + str(time.time() - start_time))\n    return centers, clusters, sizes\n\ndef create_clusters_centers(markers, zoom, radius):\n    mercator = globaltiles.GlobalMercator()\n    centers, clusters, sizes = cluster_markers(mercator, markers, zoom, radius)\n    centers_markers = [markers[i] for i in centers]\n    return centers_markers, clusters, sizes\n\ndef get_cluster_json(clust_marker, clust_size):\n    return {\n        'longitude': clust_marker.longitude,\n        'latitude': clust_marker.latitude,\n        'size': clust_size\n    }\n\ndef get_cluster_size(index, clusters):\n    from collections import Counter\n    #TODO: don't call Counter for every cluster in the array\n    return Counter(clusters)[index]\n\ndef generate_clusters_json(markers, zoom, radius=50):\n    centers, clusters, sizes = create_clusters_centers(markers, zoom, radius)\n    json_clusts=[]\n\n    for i, point in enumerate(centers):\n        json_clusts.append(get_cluster_json(point, sizes[i]))\n\n    return {\n        'clusters': json_clusts\n    }\n\n##\nif __name__ == '__main__':\n    ##\n    mercator = globaltiles.GlobalMercator()\n    latlngs = [(28.43, 8), (28.43, 8), (28.44, 8), (35, 8)]\n    centers, clusters = cluster_markers(mercator, latlngs, 21)\n    ##", "path": "static/pymapcluster.py"}], "after_files": [{"content": "##\nimport globalmaptiles as globaltiles\nfrom math import cos, sin, atan2, sqrt\nimport time\n##\n \ndef center_geolocation(geolocations):\n    \"\"\"\n    Provide a relatively accurate center lat, lon returned as a list pair, given\n    a list of list pairs.\n    ex: in: geolocations = ((lat1,lon1), (lat2,lon2),)\n        out: (center_lat, center_lon)\n    \"\"\"\n    x = 0\n    y = 0\n    z = 0\n \n    for lat, lon in geolocations:\n        lat = float(lat)\n        lon = float(lon)\n        x += cos(lat) * cos(lon)\n        y += cos(lat) * sin(lon)\n        z += sin(lat)\n \n    x = float(x / len(geolocations))\n    y = float(y / len(geolocations))\n    z = float(z / len(geolocations))\n \n    return (atan2(y, x), atan2(z, sqrt(x * x + y * y)))\n\ndef latlng_to_zoompixels(mercator, lat, lng, zoom):\n    mx, my = mercator.LatLonToMeters(lat, lng)\n    pix = mercator.MetersToPixels(mx, my, zoom)\n    return pix\n\ndef in_cluster(center, radius, point):\n    return sqrt((point[0] - center[0])**2 + (point[1] - center[1])**2) <= radius\n\ndef cluster_markers(mercator, latlngs, zoom, gridsize=50):\n    \"\"\"\n    Args:\n        mercator: instance of GlobalMercator()\n        latlngs: list of (lat,lng) tuple\n        zoom: current zoom level\n        gridsize: cluster radius (in pixels in current zoom level)\n    Returns:\n        centers: list of indices in latlngs of points used as centers\n        clusters: list of same length as latlngs giving assigning each point to\n                  a cluster\n    \"\"\"\n    start_time = time.time()\n    centers = []\n    clusters = []\n    sizes = []\n    latlngs = map(lambda latlng: latlng.serialize(), latlngs)\n    for i, latlng in enumerate(latlngs):\n        lat = latlng['latitude']\n        lng = latlng['longitude']\n        point_pix = latlng_to_zoompixels(mercator, lat, lng, zoom)\n        assigned = False\n        for cidx, c in enumerate(centers):\n            center = latlngs[c]\n            center = latlng_to_zoompixels(mercator, center['latitude'], center['longitude'], zoom)\n            if in_cluster(center, gridsize, point_pix):\n                # Assign point to cluster\n                clusters.append(cidx)\n                sizes[cidx] += 1\n                assigned = True\n                break\n        if not assigned:\n            # Create new cluster for point\n            #TODO center_geolocation the center!\n            centers.append(i)\n            sizes.append(1)\n            clusters.append(len(centers) - 1)\n\n    print('time for cluster_markers: ' + str(time.time() - start_time))\n    return centers, clusters, sizes\n\ndef create_clusters_centers(markers, zoom, radius):\n    mercator = globaltiles.GlobalMercator()\n    centers, clusters, sizes = cluster_markers(mercator, markers, zoom, radius)\n    centers_markers = [markers[i] for i in centers]\n    return centers_markers, clusters, sizes\n\ndef get_cluster_json(clust_marker, clust_size):\n    return {\n        'longitude': clust_marker.longitude,\n        'latitude': clust_marker.latitude,\n        'size': clust_size\n    }\n\ndef get_cluster_size(index, clusters):\n    from collections import Counter\n    #TODO: don't call Counter for every cluster in the array\n    return Counter(clusters)[index]\n\ndef generate_clusters_json(markers, zoom, radius=50):\n    centers, clusters, sizes = create_clusters_centers(markers, zoom, radius)\n    json_clusts=[]\n\n    for i, point in enumerate(centers):\n        json_clusts.append(get_cluster_json(point, sizes[i]))\n\n    return {\n        'clusters': json_clusts\n    }\n\n##\nif __name__ == '__main__':\n    ##\n    mercator = globaltiles.GlobalMercator()\n    latlngs = [(28.43, 8), (28.43, 8), (28.44, 8), (35, 8)]\n    centers, clusters = cluster_markers(mercator, latlngs, 21)\n    ##", "path": "static/pymapcluster.py"}]}