biodiv / anycluster

Server-side clustering of map markers for (Geo)Django
MIT License
106 stars 21 forks source link

Possible Bug in kmeansCluster(self, clustercells, filters) #11

Closed lmorroni closed 10 years ago

lmorroni commented 10 years ago

Hi, I am really getting some inconsistent behavior with anycluster and I am wondering if you could help me understand what is wrong. I am getting different results when I use anycluster from a web request and when I run it on the console. My theory is that the kmeansCluster function either has a bug with it or is not playing nice with my setup. My issue is that the map never shows a point on zoom level 3 and at other zoom levels, not all of the clusters always show. Here are my findings:

Running from the shell things look fine:

Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from anycluster.MapClusterer import MapClusterer
>>> viewport6 = {'left':133.82065082500003, 'top':66.88222838558252, 'right':28.87924457500003, 'bottom':-8.875300215087336}
>>> c = MapClusterer()
>>> c.zoom = 3
>>> c.gridSize = 128
>>> cells = c.getClusterCells(viewport6);
VIEWPORT(wgs84datum, 4326, longlat): {'top': 66.88222838558252, 'right': 28.87924457500003, 'bottom': -8.875300215087336, 'left': 133.82065082500003}
>>> print cells
['9,7', '9,8', '9,9', '9,10', '9,11', '9,12', '10,7', '10,8', '10,9', '10,10', '10,11', '10,12', '11,7', '11,8', '11,9', '11,10', '11,11', '11,12', '12,7', '12,8', '12,9', '12,10', '12,11', '12,12', '13,7', '13,8', '13,9', '13,10', '13,11', '13,12']
>>>

However, when I run this query to get back the json cells from my browser:

http://localhost:8080/anycluster/kmeans/3/128/?left=133.82065082500003&top=66.88222838558252&right=28.87924457500003&bottom=-8.875300215087336&cache=load

I get the empty set back:

[]

My theory is that the webquery is going through kmeansCluster and things are getting messed up there. I have tried this with a bunch of different google maps version. Here are the settings I am using:

var anyclusterSettings = {
    mapType: "google", // "google" or "osm"
    gridSize: 128, //integer
    zoom: 3, //initial zoom
    center: [37.9, -98.6500523], //initial center in lng lat
    MapTypeId: "TERRAIN", 
    clusterMethod: "kmeans", //"grid" or "kmeans" or "centroid"
    iconType: "exact", //"exact" (with exact cluster counts) or "simple" (with rounded counts)
    singlePinImages: {
//        'pinimg': 'icons/ppl_locations.png' //optional, use in conjunction with django settings: 'ANYCLUSTER_PINCOLUMN'
    }
}

I'm at a loss for what the cause of this is. Any ideas?

Thanks, Larry

lmorroni commented 10 years ago

Justw anted to send some additional info. I added some debug statements. I may misunderstand how anycluster functions but it seems like I have a set of cluster cells, I then get the cellpins raw SQL. I take the generated SQL and paste it in my postgresql query tool and I get no results. See the debug output below:

clustercells-->set(['10,12', '10,11', '10,10', '12,9', '12,8', '13,7', '13,8', '13,9', '12,7', '9,7', '11,8', '11,9', '11,7', '9,8', '9,9', '10,9', '10,8', '10,7', '13,12', '13,10', '13,11', '9,10', '9,11', '9,12', '12,11', '12,10', '12,12', '11,10', '11,11', '11,12'])
filters-->[]
cell-->10,12
SELECT kmeans AS id, count(*), ST_Centroid(ST_Collect(geom)) AS geom , MIN(pin) AS pinimg
                            FROM (
                              SELECT pin, kmeans(ARRAY[ST_X(geom), ST_Y(geom)], 6) OVER (), geom
                              FROM locator_placemark
                              WHERE ST_Within(geom, ST_GeomFromText('POLYGON((67.500000 74.019543, 67.500000 66.513260, 45.000000 66.513260, 45.000000 74.019543, 67.500000 74.019543))',4326) ) 
                            ) AS ksub
                            GROUP BY kmeans
                            ORDER BY kmeans;
biodiv commented 10 years ago

Thanks for reporting. I will give this a deeper look as soon as I find the time. Some quick thoughts:

Try this statement in psql query tool:

SELECT * FROM locator_placemark WHERE ST_Within(geom,ST_GeomFromText('POLYGON((67.500000 74.019543, 67.500000 66.513260, 45.000000 66.513260, 45.000000 74.019543, 67.500000 74.019543))',4326) )

to make sure the polygon contains points. I checked this exact query on my database and it returned results. If the polygon is empty it means that your database does not contain points inside this polygon. If this happens after clicking on a cluster we might have to alter the onclusterclick action in javascript to zoom in more accurately.

lmorroni commented 10 years ago

No it does not but the problem is that the polygon is not on the proper spot of the earth. I'm searching with the US and this comes back as northern Russia. Should a query with: left=133.82065082500003&top=66.88222838558252&right=28.87924457500003&bottom=-8.875300215087336

be returning a polygon of POLYGON((67.500000 74.019543, 67.500000 66.513260, 45.000000 66.513260, 45.000000 74.019543, 67.500000 74.019543))',4326) ) ?

biodiv commented 10 years ago

Thanks for posting this. I identified the bug. The topleft point is interpreted as topright and bottomright is interpreted as bottom left. A fix of this should not be too complicated and has to be done in get_ClusterCells of MapTools.py. I will release a fix asap.

lmorroni commented 10 years ago

I am glad you found this! I have been tracing through your code and was starting to question server/dev environment setup. Thanks! Larry

biodiv wrote:

Thanks for posting this. I identified the bug. The topleft point is interpreted as topright and bottomright is interpreted as bottom left. A fix of this should not be too complicated and has to be done in |get_ClusterCells| of |MapTools.py|. I will release a fix asap.

— Reply to this email directly or view it on GitHub https://github.com/biodiv/anycluster/issues/11#issuecomment-39777849.

biodiv commented 10 years ago

I uploaded changes that should fix this issue now - please report if it worked.

lmorroni commented 10 years ago

That did it. You are the man! Thanks! Larry